2011-02-27 37 views
1
一個String

可能重複:
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,也可以不匹配?

+0

單詞「正則表達式」是小寫,而不是全部大寫。 – 2011-02-27 21:58:54

回答

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丟失時的情況。

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:/

0

只需使用問號操作員的組後你想成爲可選的,所以在這種情況下:

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

一定要匹配的空間爲好,否則弦無AM/PM需要包括兩個空間。與(?:AM|PM)*解決方案也將匹配AMAMPM,所以這可能不是你想要的。但是,爲什麼你在沒有創建反向引用的情況下匹配那些組?你不打算使用這些值嗎?

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