用Python regex在\d中进行意外的逗号匹配

2024-10-03 13:19:58 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图构建一个正则表达式来匹配Python中的字符串,比如“<;StringNumber>;”。正则表达式应该拒绝在逗号之后和右括号之前没有一个整数的字符串(英文中称为括号吗?)。但是,\d和[0-9]regex匹配内部逗号,因此例如,我得到的是

re.match('<.+?,\d+>', '<Year,4,4>')

但是,奇怪的是,不是

re.match('<.+?,\d+>', '<Year,4.4>')

是我错了还是\d不应该与逗号匹配? 我真的不认为是这样的,但是我在阿根廷,所以小数点实际上是逗号,而不是点,python是否可以使用我的系统语言来解决这个问题,并将逗号考虑到“数字”中?但是,据我所知,这不会是\d的情况,因为它不应该包括除[0-9]以外的任何内容,对吗?你知道吗

有人能帮我解决这个问题吗?我正在运行python2.7.3

上下文:如果在<;和>;字符之间只包含一个字符串,则将整个内容保存为一个符号,否则只保存逗号之前的字符串,并使用数字构建正则表达式

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

谢谢!你知道吗


Tags: 字符串ltgtre内容match数字year
2条回答

你所遇到的,以及使你的正则表达式失败的,叫做回溯。你知道吗

看看regex引擎在这里采取的步骤:

#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

在声明失败之前,regex引擎必须尝试所有不同的可能性。它可以选择在第一个或第二个逗号处停止.+?循环,第二个逗号起作用,它返回找到的匹配项。你知道吗

正如BrenBarn所说,为了避免这种行为,您必须强制它考虑第一个逗号,因此这确实是一种方法([^,]表示除逗号以外的任何字符):

<[^,]+,\d+>

\d与逗号不匹配。.+?匹配第一个逗号,因为.匹配任何字符,包括逗号。如果您不想在“string”部分中使用逗号,请使用类似r"<[^,]+,\d+>"的正则表达式排除它们。你知道吗

注意,非贪婪限定符在这里没有帮助。使用.+?意味着它将尝试匹配尽可能少的字符,但它仍将匹配它所需的尽可能多的字符,以便使整个regex匹配(如果可以的话)。由于您要求它在逗号后匹配\d,因此它仍将使用第一个逗号,以便达到可以匹配,\d的点。你知道吗

相关问题 更多 >