2

可能重复:
如何在 Ruby 中将正则表达式的一部分设为可选?

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

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

或者

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,要么都不匹配?

4

3 回答 3

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 丢失时处理它。

于 2011-02-27T01:36:51.977 回答
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" 开头并以 "wrote:" 结尾,那么您的正则表达式可能很简单/^On.*wrote:/

于 2011-02-27T01:31:18.193 回答
0

只需在您希望成为可选的任何组之后使用问号运算符,因此在这种情况下:

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

一定要匹配空格,否则没有 AM/PM 的字符串需要包含两个空格。的解决方案(?:AM|PM)*也将 match AMAMPM,所以这可能不是你想要的。但是你为什么要匹配这些组而不创建反向引用?你不打算使用这些值吗?

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

于 2011-02-27T02:05:24.040 回答