这个社区对我之前的正则表达式问题帮助很大,我确实对这两个正则表达式有了疑问。
我的目标是让正则表达式为:日期或日期时间戳
date =(\ d {1,2} | [a-zA-Z] {2,8})(?:[/ - ] {1})(\ d {1,2} | [a- ZA-Z] {2,8})(?:[/ - ] {1})(\ d *)
timestamp =(\ d {1,2})(?:[:] {1})(\ d {1,2})(?:[:] {1})(\ d {1,2 })
我无法将这两者合并为一个单一的正则表达式语句。任何帮助都会很棒!
答案 0 :(得分:2)
首先,我建议您简化模式。它们包含很多冗余,而且似乎是一些疏忽。
您的时间戳模式:(\d{1,2})(?:[:]{1})(\d{1,2})(?:[:]{1})(\d{1,2})
我将继续并假设您确实需要捕获组,以便您可以在程序中返回月/日/年,但是对于它的价值,没有理由在此正则表达式中对任何内容进行分组。因此,可以删除非捕获组。
(\d{1,2})[:]{1}(\d{1,2})[:]{1}(\d{1,2})
没有理由将:
放在方括号内,因为它只有一个字符,它在括号内外都有相同的含义(例如,与.
相对)。此外,{1}
在所有情况下都是多余的。
(\d{1,2}):(\d{1,2}):(\d{1,2})
这取决于个人意见,但我更喜欢写两次,然后是?
而不是{1,2}。而且,我猜这是一个疏忽,你只允许一年的一位数。那会很奇怪。
(\d\d?):(\d\d?):(\d\d)
好多了,对吧?
现在让我们来看看你的“日期”模式:
(\d{1,2}|[a-zA-Z]{2,8})(?:[/-]{1})(\d{1,2}|[a-zA-Z]{2,8})(?:[/-]{1})(\d*)
快速应用我提到的第一个模式的所有更改。
(\d\d?|[a-zA-Z]{2,8})[/-](\d\d?|[a-zA-Z]{2,8})[/-](\d*)
我很想知道你是否真的需要检查第一和第二部分中可能由字母组成的字符串。通常它是一个或另一个取决于区域,但很少在同一程序中混合两者。我将继续删除检查这个的第二部分,但当然要继续并在需要时将其重新添加。无论如何,最后的\d*
看起来可能是个问题。我怀疑你希望这一年包含0,1或4位以上。
(\d\d?|[a-zA-Z]{2,8})[/-](\d\d?)[/-](\d{2,4})
(你可能不希望这一年也包含3位数字,但这可能已经足够了。)
现在我们有了这两种简化模式,问题是如何将它们组合起来。最直接和最一致的方法是将它们中的两个放在一起,用|
分隔。
(\d\d?|[a-zA-Z]{2,8})[/-](\d\d?)[/-](\d{2,4})|(\d\d?):(\d\d?):(\d\d)
但是,由于它们彼此非常相似,因此只需将:
分隔符添加到第二个模式即可将它们混合在一起。
(\d\d?|[a-zA-Z]{2,8})[:/-](\d\d?)[:/-](\d{2,4})
请注意,这可能会产生一些意想不到的匹配。例如,July:23-1999
。分隔符之间的潜在不匹配在您的“日期”模式中已经有些固有,但现在通过添加:
会变得更糟。如果这是一个问题,您可以捕获第一个分隔符,然后在需要时再匹配它。
(\d\d?|[a-zA-Z]{2,8})([:/-])(\d\d?)\2(\d{2,4})
但请注意,这将更改捕获组的顺序,因此如果您的程序依赖于\ 1,\ 2和\ 3,则现在需要使用\ 1,\ 3和\ 4。
使用有效和无效的数据:https://regex101.com/r/cRAw1Y/1
答案 1 :(得分:1)
final = '(' + date + ')|(' + date + ')(' + timestamp ')'
如果我们还假设我们在日期和时间戳之间有分隔符的正则表达式,我们可以使用
final = '(' + date + ')|((' + date + ')(' + separator + ')(' + timestamp + '))'
如果这对您不起作用,请解释原因。