2015-11-01 56 views
1

比賽日我想編輯的試圖從一段文本中提取日期一些現有的正則表達式。由於我對正則表達式不太熟練,我認爲這是學習新內容的好時機。正則表達式在一個月

所以我有以下的正則表達式:

r'\b0*[1-9]?[0-9]\b' 

它(如果我理解正確的話)檢索與零個或多個0的開頭的號碼,然後按零個或多個數字1和9之間,和0和9之間的1個數字因此,它匹配下面:

10 
24 
01 

,但它也符合以下的事情(這顯然不是日期)

94 
0000024 

雖然它不符合以下(這實際上是日期):

1st 
3rd 
5th 

所以我開始放話我需要什麼,並試圖寫它後面的正則表達式是什麼我趕上了:

  1. 一個以空格,短劃線,斜線或任何東西開頭的字符串(即直接與數字開始)
    • 我嘗試:\b|-|\/
  2. 共有字符串中1個或2的數字。數字在一起應該在1到31之間,不管是否爲前導零。
    • 我嘗試:[1-9]|0[1-9]|[1-2][0-9]|3[0-1]
  3. 要麼其次是 「ST」, 「第二」, 「第三」, 「日」,破折號,斜線或空格。
    • 我嘗試:st|nd|rd|th|-|\/|\b

把這個在一起那就是:\b|-|\/[1-9]|0[1-9]|[1-2][0-9]|3[0-1]st|nd|rd|th|-|\/|\b

但是,這似乎並沒有在所有的工作。當我測試第二部分(數字)時,它幾乎匹配我輸入的所有數字。

我不想將此作爲give me ze code的問題,但是有沒有人可以通過指出我在做什麼來幫助我錯誤?我真的很想學習使用正則表達式。

歡迎所有提示!

ps。我知道有些月份有更少的天數超過31個,但我不得不開始學習的地方..

[編輯]

所以要明確(@Saraiva問這個在評論)。我希望它匹配以下:

01 
08 
9 
28 
31 
2nd 
31st 
/31st 
-22nd/ 
/25- 

但不是這樣的:

73 
01200 
026 
/2200nd- 
(6th 
+0

_「這(如果我理解正確)開始檢索的數與零級或更多0的,其次是1和9,以及0到9" 之間1號之間的零個或更多的數字_不,它'0(0+次),[1-9](0-1次),[ 0-9](1次)' –

+0

你可以給它一些日期的樣本,它應該匹配?如05/12/2012或1st-fev-2015? –

+0

這些應該是在文本字符串/行的開始? – Amit

回答

1

你的正則表達式的片段是正確的,你只是做是錯誤的如何把它放在一起。如果你這樣做:

\b|-|\/[1-9]|0[1-9]|[1-2][0-9]|3[0-1]st|nd|rd|th|-|\/|\b 

你的or-ing(|)的一切(是這樣,你匹配一個單詞邊界,或破折號,或......)。

你想是這樣的:

(?:\b)(([1-9]|0[1-9]|[1-2][0-9]|3[0-1])(st|nd|rd|th)?)(?:\b|\/) 

這樣:

a word boundary (non capturing) 
followed by a number 0-31 
followed (eventually) by one of st nd rd th 
followed by a word boundary (non capturing) or a slash 

這裏舉例:https://regex101.com/r/zM4lI5/3

你可能會得到更好的結果,如果切換到使用環視:

(?<=\b|\/|-)((?:[1-9]|0[1-9]|[1-2][0-9]|3[0-1])(?:st|nd|rd|th)?)(?=\b|\/|-) 

(?<=\b|\/|-) whatever matches the following, if preceded by this 
(?=\b|\/|-) whatever matched the preceding, if followed by this 

樣品:https://regex101.com/r/zM4lI5/4

編輯:

如果你只是想捕捉的數字,我會改變這樣的rexgex,與非捕獲組比賽:

(?<=\b|\/|-)([1-9]|0[1-9]|[1-2][0-9]|3[0-1])(?:st|nd|rd|th)?(?=\b|\/|-) 

編輯2:好吧,我看到Python要求隱藏式斷言具有恆定的長度;在我們這裏,\b是0,而\/-是1個字符。如果是對你有好處,我建議只使用,而不是單詞邊界的空白:

(?<=\s|\/|-)([1-9]|0[1-9]|[1-2][0-9]|3[0-1])(?:st|nd|rd|th)?(?=\b|\/|-) 

樣品在這裏:IDEONEregex101

+0

哇,你真棒。到目前爲止,最後的版本確實是最好的。我是否也可以用'st | nd | rd | th'來替代它,這樣我得到的結果只是數字? – kramer65

+0

所以我改成了這一點:' - (((<= \ b | | \ /):[1-9] | 0 [1-9] | [1-2] [0-9] | 3? [0-1])?)(?= \ b | \/| - | st | nd | rd | th)'這似乎是做我想要的。我現在把它放在我的Python腳本中:如下所示:'re.finditer(DAY_NUM_RE,'check this:2nd')'這給了我一個'錯誤:後顧需要固定寬度的模式。任何想法我怎麼能解決這個問題?或者我應該問一個新的問題? – kramer65

+0

固定寬度的模式錯誤你,是因爲你不能在你量詞lookarounds,但鑑於上述正則表達式的,它似乎並不如此呢? (實際上,它似乎支持python在這裏:https://regex101.com/r/zT6dG1/2)。反正不是,如果你用它這樣的,這是不正確的(先行將是'或第一句話boundary') –