2016-10-25 61 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的输入,我最终使用了一些代码:)