2016-10-25 62 views
3

我試圖建立一個正則表達式來捕獲任何數字(整數,浮點數,或不帶科學記數法)。即時通訊使用組,以便如果我需要更新的東西,我只更新一行。下面是我在做什麼:Python正則表達式命名組

intNumber = r"(?P<Integer>-?(0|[1-9]+[0-9]*))" # Integer 
floatNumber = r"(?P<Float>"+intNumber+r"\.[0-9]+)" # Float 
sciNumber = r"(?P<Scientific>"+floatNumber+r"(e|E)(-|\+)?[0-9]+)" # Scientific 
anyNumber = r"(?P<AnyNumber>"+sciNumber+"|(?P=Integer)|(?P=Float))" # Any number 

的問題是,雖然每個正則表達式的工作對自己,當我使用或結合他們都在anyNumber|)它抓住了唯一的科學記數法表示,而不是休息。我究竟做錯了什麼?

編輯:要優化我的問題,是有可能有一個動態生成的正則表達式(與記簡單的單點維護的目的),也具有足夠的靈活性,讓我單獨使用其組成部分,沒有問題像重新定義組和方便地命名組?我知道我可能會問太多..

+0

嘗試http://ideone.com/fu9eOy –

回答

0

(?P=Integer)是一個名爲反向引用相匹配的相同的文本(不遞歸組子模式!),通過一個名爲「整數」捕獲組匹配。與(?P=Float)一樣。這意味着,你需要使用模式本身,而不是反向引用。

另外,如果您打算以這種方式動態構建正則表達式,則不能使用指定的反向引用。使用非捕獲組和你的模式建設將類似於

import re 
intNumber = r"-?(?:0|[1-9]+[0-9]*)" # Integer 
floatNumber = intNumber+r"\.[0-9]+" # Float 
sciNumber = floatNumber+r"[eE][-+]?[0-9]+" # Scientific 
anyNumber = r"{0}|{1}|{2}".format(sciNumber,floatNumber,intNumber) # Any number 
print(re.findall(anyNumber, '12 12.34 12.34E-34')) 

Python demo

+0

好的,謝謝!但是,如果我也想引用intNumber組整數或組Float,因爲我將單獨使用它們(而不僅僅用於創建anyNumber正則表達式),那麼我需要捕獲組。在那種情況下,如果我可以命名捕獲組,那將非常棒。 查看我的問題編輯:) – capitan

+0

你不能在're' regex中使用兩個同名的命名組。如果您的模式定義爲'r「{0} | {1} | {2}」格式(sciNumber,floatNumber,intNumber)'',那麼您會得到一個異常。你可以考慮使用PyPi正則表達式模塊,或者忘記這樣深層的命名。 –

0

最後我做了以下內容:

intNumber_re = r"(?P<Integer>-?(0|[1-9]+[0-9]*))" # Integer 
floatNumber_re = r"(?P<Float>"+intNumber_re+r"\.[0-9]+)" # Float 
sciNumber_re = r"(?P<Scientific>"+floatNumber_re+r"[eE][-\+]?[0-9]+)" # Scientific 
groupNames_re = r'(\?P<Integer>)|(\?P<Float>)|(\?P<Scientific>)' 
anyNumber_re = r"(?P<AnyNumber>{0}|{1}|{2})".format(re.sub(groupNames_re,'?:',sciNumber_re), 
       re.sub(groupNames_re,'?:',floatNumber_re),re.sub(groupNames_re,'?:',intNumber_re)) # Any number 

有效,我去掉組名(當我構造具有re.sub()函數的anyNumber RE時,那些正則表達式在groupNames_re)。這有點醜陋,但它的工作原理和我想要的靈活性。感謝Wiktor的輸入,我最終使用了一些代碼:)