使正则表达式的一部分可选

时间:2011-03-28 01:29:24

标签: ruby regex

这是我的正则表达式:

/On.* \d{1,2}\/\d{1,2}\/\d{1,4} \d{1,2}:\d{1,2} (?:AM|PM),.*wrote:/

匹配:

On 3/14/11 2:55 PM, XXXXX XXXXXX wrote:

我需要这个Regex也匹配:

On 25/03/2011, at 2:19 AM, XXXXX XXXXXXXX wrote:

所以我尝试了这个:

/On.* \d{1,2}\/\d{1,2}\/\d{1,4}(, at)? \d{1,2}:\d{1,2} (?:AM|PM),.*wrote:/

但这打破了其他比赛

我是否(?)?可选设置对吗?

由于

3 个答案:

答案 0 :(得分:1)

我稍微改变了你的Regex,我能够匹配两个字符串。我的正则表达式是:

/On.* \d{1,2}\/\d{1,2}\/\d{1,4}(?:, at)? \d{1,2}:\d{1,2} (?:AM|PM),.*wrote:/ 

比较两者的结果:

irb(main):023:0> s1 = "On 25/03/2011, at 2:19 AM, XXXXX XXXXXXXX wrote:"
=> "On 25/03/2011, at 2:19 AM, XXXXX XXXXXXXX wrote:"
irb(main):024:0> s2 = "On 3/14/11 2:55 PM, XXXXX XXXXXX wrote:"
=> "On 3/14/11 2:55 PM, XXXXX XXXXXX wrote:"
#Your previous Regex
irb(main):025:0> m = /On.* \d{1,2}\/\d{1,2}\/\d{1,4}(, at)? \d{1,2}:\d{1,2}(?:AM|PM),.*wrote:/
=> /On.* \d{1,2}\/\d{1,2}\/\d{1,4}(?:, at) \d{1,2}:\d{1,2} (?:AM|PM),.*wrote:/
irb(main):026:0> s1.match(m)
=> #<MatchData "On 25/03/2011, at 2:19 AM, XXXXX XXXXXXXX wrote">
irb(main):027:0> s2.match(m)
=> nil

#The updated Regex
irb(main):028:0> m = /On.* \d{1,2}\/\d{1,2}\/\d{1,4}(?:, at)? \d{1,2}:\d{1,2} (?:AM|PM),.*wrote/
=> /On.* \d{1,2}\/\d{1,2}\/\d{1,4}(?:, at)? \d{1,2}:\d{1,2} (?:AM|PM),.*wrote/
irb(main):029:0> s1.match(m)
=> #<MatchData "On 25/03/2011, at 2:19 AM, XXXXX XXXXXXXX wrote">
irb(main):030:0> s2.match(m)
=> #<MatchData "On 3/14/11 2:55 PM, XXXXX XXXXXX wrote">

答案 1 :(得分:0)

以下正则表达式适用于这两种情况:

On\s*\d{1,2}\/\d{1,2}\/\d{1,4}[\s,]*(at)?\s*\d{1,2}:\d{1,2}\s*(?:AM|PM),\s*.*wrote:

答案 2 :(得分:0)

其他输入字符串的问题可能是由.*成语引起的。它很贪婪,想要从输入中尽可能多地消耗它。

如果您的输入是是一个日期,然后是一些随机文本,然后是另一个日期 - 那么你的正则表达式会认为两个日期和随机文本是一个日期。其中大部分将由.*使用。

在大多数情况下,最好使用a lazy quantifier。从语法上讲,您可以编写.*?而不是.*。你有两个.*。尝试用.*?

替换它们
/On.*? \d{1,2}\/\d{1,2}\/\d{1,4}(, at)? \d{1,2}:\d{1,2} (?:AM|PM),.*?wrote:/

如果这不起作用,您必须在此处发布失败日期,您肯定会从此社区获得更多反馈。