我正在尝试构建一个正则表达式来匹配字符串,如"< String , Number >"在Python中。正则表达式应该拒绝任何在逗号之后和结束括号之前没有单个整数的字符串(在英语中称为括号?)。但是,\ d和[0-9]正则表达式匹配内部逗号,所以例如我得到匹配
re.match('<.+?,\d+>', '<Year,4,4>')
但是,奇怪的是,不是
re.match('<.+?,\d+>', '<Year,4.4>')
我错了还是\ d不应该与逗号匹配? 我真的不认为是这种情况,但我在阿根廷所以小数点实际上是这里的逗号而不是重点,python是否可以使用我的系统语言来计算出来并使用逗号考虑到&#34;数字&#34;?但是,据我所知,这种情况并非如此,因为除了[0-9]之外它不应该包含任何内容,我是对的吗?
有人可以帮我解决这个问题吗?我正在运行Python 2.7.3
上下文:如果&lt; 之间只包含一个字符串和&gt; chars,将整个事物保存为符号,否则只保存逗号前的字符串并使用数字构建正则表达式
def compileRegex(self, r=''):
r += '//'
symbols = []
numeratedTracker = r'<(.+?),(\d+)>'
simpleTraker = r'<(.+?)>'
preSymbols = re.findall('<.+?>', r)
# Fill the symbol list and build the tracking regex
for s in preSymbols:
# Numerated symbol
numeratedMatch = re.match(numeratedTracker, s)
if numeratedMatch:
symbolAndNumber = s[1:-1].split(',')
symbols.append(symbolAndNumber[0])
subregex = '.{' + symbolAndNumber[1] + '}'
else:
symbols.append(s[1:-1])
subregex = '(.+?)'
re.sub(s, subregex, r)
return symbols, r
谢谢!
答案 0 :(得分:4)
\d
与逗号不匹配。 .+?
与第一个逗号匹配,因为.
匹配任何字符,包括逗号。如果您不想在&#34;字符串中使用逗号&#34;部分,使用像r"<[^,]+,\d+>"
这样的正则表达式排除它们。
请注意,非贪婪的限定符在这里没有帮助你。使用.+?
表示它会尝试匹配尽可能少的字符,但它仍然会匹配需要的数量,以便使整个正则表达式匹配,如果可以的话。由于您要求它在逗号后面与\d
匹配,因此它仍将使用第一个逗号,以便达到可与,\d
匹配的点。
答案 1 :(得分:2)
您遇到的问题以及使您的正则表达式失败的原因称为回溯。
查看正则表达式引擎在此处采取的步骤:
#1. (<).+?,\d+>
<Year,4,4>
^
#2. <(.+?),\d+> leads us up to
<Year,4,4>
^
#3. <.+?(,\d+)>
<Year,4,4> # because of the lazy quantifier, the regex gives priority to `,`
^ # before the `.+?` repetition: as soon as it find one it tries and
# gets out of the `.+?` loop
#4. <.+?,\d+(>)
<Year,4,4> # failure and backtracking, the regex engine comes back to the
x # last position where it had a choice, aka step 2:
#2. <(.+?),\d+>
<Year,4,4>
^
#5. <(.+?),\d+>
<Year,4,4> # this time it tries the other possibility:
^ # the first `,` is matched inside the `.+?`
#6. <.+?(,\d+>)
<Year,4,4>
^ # an overall match is found
在声明失败之前,正则表达式引擎必须尝试所有不同的可能性。它可以选择在第一个或第二个逗号处停止.+?
循环,第二个逗号停止,它返回找到的匹配。
正如BrenBarn所说,为了避免这种行为,你必须强制它考虑第一个逗号,所以这确实是要走的路([^,]
意味着任何字符而不是逗号):
<[^,]+,\d+>