我试图构建一个捕获任何数字的正则表达式(整数,浮点数,带有科学记数法)。我使用组,所以如果我需要更新的东西,我只更新一行。这就是我正在做的事情:
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 :(得分:0)
(?P=Integer)
是一个名为的反向引用,与相同的文本(不是递归组子模式!)匹配,与名为&#34的捕获组匹配;整数&#34 ;.与(?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
答案 1 :(得分: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
当我使用groupNames_re
函数构造anyNumber
RE时,我有效地删除了组名(正则表达式在re.sub()
中)。它有点难看,但它起作用,给了我我想要的灵活性。感谢Wiktor的输入,我最终使用了一些代码:)