正则表达式回溯多个条件

问题描述 投票:0回答:4

我有一个字符串,可能如下(1种可能性):

"1/1/2024; 02/01/2024; 2024-10-01" 

我想(从右侧)返回多种可能的日期格式的最后一次出现:

mm/dd/yyyy, mm/dd/yy, yyyy-mm-dd, m/dd/yyyy, m/d/yyyy

因此从上面的示例中,仅查找并返回

2024-10-01
。我怎样才能做到这一点?我正在考虑使用带有 OR 条件的回溯,但它不起作用:

(?!\d{2}/\d{2}/\d{4}|\d{2}/\d{2}/\d{2}|\d{4}-\d{2}-\d{2}|\d{1}/\d{2}/\d{4}|\d{2}/\d{1}/\d{4}|\d{1}/\d{1}/\d{4})
python regex
4个回答
1
投票

为此,您不需要正则表达式,只需在

;
上拆分字符串并将最后一个值转换为日期对象即可。如果您已经加载了
pandas
,您可以使用
to_datetime
它将根据您的输入字符串猜测格式:

import pandas as pd

s = "1/1/2024; 02/01/2024; 2024-10-01"
out = pd.to_datetime(s.split(';')[-1]).date()

输出:

datetime.date(2024, 10, 1)

然后可以使用

strftime
(例如)进行格式化:

out.strftime('%m/%d/%Y')

输出:

'10/01/2024'

1
投票

安装 PyPi

regex
模块 (
pip install regex
) 并运行

import regex

text = "1/1/2024; 02/01/2024; 2024-10-01"
rx = r"\b(\d{4}-\d{2}-\d{2}|\d\d?/\d\d?/\d{2}(?:\d{2})?)\b"
match = regex.search(rx, text, regex.REVERSE)
if match:
    print(match.group())

查看在线演示

regex.REVERSE
标志 从字符串末尾搜索匹配项,因此您会得到 last 出现的位置。

注意我在模式的两侧添加了单词边界,以确保您只将日期作为整个单词进行匹配,并稍微缩小了模式。请参阅此处正则表达式演示


0
投票
// Convert single digit `d-m` or  `m-d` to double digit format `dd-mm` or `mm-dd`

txt.replace(/(^|(?<=[;\s*\/\-]))\d{1}((?=[\/\-;\s])|$)/g, '0$&')

// split with ;  and then trim
.split(';').map(x => x.trim())

// finally matching regex format what you expect
.filter(x => (x.match(/^((\d{2}[\/\-]){2}\d{4})$/g) || x.match(/^(\d{4}([\/\-]\d{2}){2})$/g) ||  x.match(/^(\d{2}[\/\-]){2}\d{2}$/g))) 

完整代码在这里:

let txt = "1/1/2024; 2/1/2024; 2024-10-1; 3/3/2024; 2005-3-3; 24-06-06";

let res = txt.replace(/(^|(?<=[;\s*\/\-]))\d{1}((?=[\/\-;\s])|$)/g, '0$&').split(';').map(x => x.trim())
.filter(x => (x.match(/^((\d{2}[\/\-]){2}\d{4})$/g) || x.match(/^(\d{4}([\/\-]\d{2}){2})$/g) ||  x.match(/^(\d{2}[\/\-]){2}\d{2}$/g))) ;

console.log(res);

我的结果包含格式:

let txt = "1/1/2024; 2/1/2024; 2024-10-1; 3/3/2024; 2005-3-3; 24-06-06";

let res = txt.replace(/(^|(?<=[;\s*\/\-]))\d{1}((?=[\/\-;\s])|$)/g, '0$&').split(';').map(x => x.trim())
.filter(x => (x.match(/^((\d{2}[\/\-]){2}\d{4})$/g) || x.match(/^(\d{4}([\/\-]\d{2}){2})$/g) ||  x.match(/^(\d{2}[\/\-]){2}\d{2}$/g))) ;

console.log(res);

mm/dd/yyyy, mm/dd/yy, yyyy-mm-dd, m/dd/yyyy, m/d/yyyy

谢谢你


0
投票

如果末尾的日期前面有一个空格(或逗号或分号),那么您可以像这样捕获最后一个日期:

year, month, day separator are | or -
  1. 您可以在此处在线查看此示例,包括每部分的说明

  2. 通过括号进行的分组在这里得到了更好的解释。

© www.soinside.com 2019 - 2024. All rights reserved.