正则表达式将字符串与可选条件匹配

时间:2011-02-27 01:10:22

标签: ruby regex rubular

  

可能重复:
  How do I make part of a regular expression optional in Ruby?

我正在尝试使用rubular构建一个正则表达式来匹配:

On Feb 23, 2011, at 10:22 , James Bond wrote:

OR

On Feb 23, 2011, at 10:22 AM , James Bond wrote:

这是我到目前为止所拥有的,但由于某种原因,它不匹配?想法?

(On.* (?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) \d{1,2}, [12]\d{3}.* at \d{1,2}:\d{1,2} (?:AM|PM),.*wrote:)

如何使AM / PM文本可选?是匹配AM / PM还是两者都没有?

3 个答案:

答案 0 :(得分:1)

这似乎抓住了日期信息。我故意在小组中捕捉,更容易建立一个真实的日期:

regex = /^On (\w+ \d+, \d+), \w+ (\S+) (\w*)\s*,/

[
  'On Feb 23, 2011, at 10:22 , James Bond wrote:',
  'On Feb 23, 2011, at 10:22 AM , James Bond wrote:'  
].each do |ary|
  ary =~ regex
  puts "#{$1} #{$2} #{$3}"
end
# >> Feb 23, 2011 10:22 
# >> Feb 23, 2011 10:22 AM

我打算在这几个月没有尝试匹配。您的示例字符串看起来像电子邮件中的引用标题。这些是非常标准的并且由软件生成,因此您应该在格式中看到很多一致性,允许在正则表达式中进行一些简化。如果您不能信任这些,那么请使用月份名称缩写上的匹配来帮助忽略误报匹配。同样的事情适用于日,年和时间值。

正则表达式中最重要的是如何在AM / PM丢失时处理它。

答案 1 :(得分:0)

也许这个

(On\s+(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s+\d{1,2},\s+[12]\d{3},\s+at\s+\d{1,2}:\d{1,2}\s+(?:AM|PM)*,.*wrote:)

但是,如果您可以验证并确保只有这些行是唯一的,则不必使用整个范围的正则表达式。也许它以“On”开头,以“write:”结尾,你的正则表达式可能很简单/^On.*wrote:/

答案 2 :(得分:0)

只需在任何想要选择的组后使用问号运算符,所以在这种情况下:

(?:(?:AM|PM) )?

确保匹配空间,否则没有AM / PM的字符串需要包含两个空格。 (?:AM|PM)*的解决方案也会匹配AMAMPM,因此可能不是您想要的。但是为什么你在没有创建反向引用的情况下匹配这些组?你不打算使用这些值吗?

有关反向引用的信息: http://www.regular-expressions.info/brackets.html