2012-10-25 85 views
1

這是我第一次使用正則表達式進行模式匹配的經驗,所以 任何幫助表示讚賞。Python正則表達式 - 模式匹配

我想搜索的字符串爲以下字符串:

"(TPU 1-999) 
http://somewebaddress.com" 

我想保持TPU1-999並作爲獨立的子鏈接。

這是我使用的模式:

^\s{3}\(([AEINPRSTUW]{3})\s(\d{1,3}.\d{2,5})\)$^\s{3}(http+\s{1,100})$ 

我會打破它來解釋我的推理

^\s{3} - 字符串(或線在這種情況下)的開頭,後面3位

\( - 左括號

([AEINPRSTUW]{3}) - 任何字母的3個實例在括號中, TPU是一個示例

\s(\d{1,3}.\d{2,5}) - 一空間,然後1-3位數字,從2-5更多位數字

\)$通過任何炭分離 - 右括號,線

^\s{3}的端 - 開始之後是三個空格

(http+\s{1,100})$ - 字符「http」後面跟着1到100之間的任何非空格字符,以及行尾。

這種模式現在不工作,但我是在正確的方向?

+0

那些是'「'您的字符串實際上一部分,那些人在那裏三個空間,你要匹配 –

回答

4

$^這是行不通的。 $是行結束(換行前),^是行的開始(行換行後)。但換行符是一個字符(或兩個),但不會提高正則表達式引擎的位置。因此,$^嘗試匹配相同的位置,如果它們是空行的結尾和開頭,它們只能發生 - 即使按照這種順序放置它們也會很有誤導性。如果你想確保恰好有他們之間的一個換行符,試試這個:

^\s{3}\(([AEINPRSTUW]{3})\s(\d{1,3}.\d{2,5})\)$(\r\n?|\n)^\s{3}(http+\S{1,100})$ 

然而,正如ridgerunner指出了評論,以下\s{3}可以匹配(最多3個)更換行符,因爲它們是空格也是如此。

另請注意,.作爲數字的分隔符可能不是最好的主意。至少,使用非數字字符:

^\s{3}\(([AEINPRSTUW]{3})\s(\d{1,3}\D\d{2,5})\)$(\r\n?|\n)^\s{3}(http+\S{1,100})$ 

還請注意,我已經改變了過去\s\S(因爲\s是空白,\S非空格)。

另請注意,您向我們顯示的字符串不包含您試圖匹配的那三個空格。所以使他們可選的(如CaptainMurphy建議)可能會有所幫助,也:

^\s*\(([AEINPRSTUW]{3})\s(\d{1,3}\D\d{2,5})\)$(\r\n?|\n)^\s*(http+\S{1,100})$ 

既然我們已經匹配換行符,我們也可以刪除這些錨有完全,他們並不真正幫助更多:

^\s*\(([AEINPRSTUW]{3})\s(\d{1,3}\D\d{2,5})\)(\r\n?|\n)\s*(http+\S{1,100})$ 
+0

非常感謝 - ?一個巨大的幫助 – TheMightyAlpaca

+0

+1,但幾個百分點。首先,在技術上,'。 $ ^'本身與空行匹配(就像'^ $'一樣) - 多個相鄰零寬度斷言的順序並不重要(儘管在這個正則表達式的上下文中它永遠不會匹配)第二,'(\ r \ n?| \ n)\ s *'不能保證只有一個新行,因爲'\ s *'匹配回車符和換行符,否則很好的解釋。 – ridgerunner

+0

@ridgerunner,you當然是絕對正確的!我將補充說明 –

1

我認爲你對大寫字母和特定數量的空白(你的示例字符串甚至在開始時沒有空白)等東西過於具體。除非我正在尋找非常具體的東西,否則我大多隻是堅持*和+。另一個答案指出,$是整個記錄(字符串)的結束,而不是行的結尾。換行符或CRLF只是空格。不要使用\ s,甚至對於非空白使用[^ \ s],請使用\ S。

ss="(TPU 1-999)\nhttp://something.com" 
rr="^\s*\(([A-Z]+)\s+(\d+.\d+)\)\s+(http\S{1,100})$" 
re.match(rr,ss).groups() 
('TPU', '1-999', 'http://something.com') 
+0

非常感謝,真的幫了很大的忙。 – TheMightyAlpaca

1

我真的在想這個。這裏是我想出了基於我所提供的答案的解決方案:

這裏是我解析字符串的例子(從電子郵件中的內容拉):

'The writeboard named "10/26 newsletters (Pat)" has been created:\r\n\r\n (TPU 1000+)\r\n\r\n http://www.techproductupdate.com/resources/2313/splunk-app-for-vmware-delivers-insight-into-the-cloud\r\n\r\n (TIN 250+)\r\n\r\n http://www.techproductupdate.com/resources/2369/securing-mysql-databases\r\n\r\n (TPU 500+)\r\n\r\n http://www.techproductupdate.com/resources/2333/designing-a-data-protection-strategy-with-hp-lefthand-hp-storeonce-and-hp-tape\r\n\r\n- - -\r\nYou can visit the writeboard at:\r\n http://somewebsite.com\r\n'

所以,首先我只是用re.findall使用模式'\((?P<list>[A-Z]*)\s(?P<segments>.+)\)'

然後我用re.findall使用模式'http\S*'找到所有的URL來定位括號之間的一切 - 這將返回所有我想要的結果,具有額外'http://somewebsite.com'在列表的末尾。

然後,我只是將這些列表壓縮在一起,不包括最後一個列表的最後一個元素,我基本上得到了我一直在尋找的結果。