正则表达式:使负面看起来“贪婪”

问题描述 投票:0回答:2

我有一个来自earlier question的以下Python正则表达式模式:

regex_pat = re.compile('''
            (
            [a-zA-Z\*]*
            \*
            [a-zA-Z\*]*
            )+           
          ''', re.VERBOSE) 

现在,如果任何数字与“单词”混合,我希望匹配失败,尤其是在开头或结尾。

text = '''
    (A) Match these:
    *** star* st**r

    (B) Not these:
    800*m *4,500 

    (C) And not these:
    800**m **4,000
    '''

通过在不同的地方尝试一对负前瞻和负面的后视,我可以摆脱(B)匹配,但不是(C)匹配。例如:

regex_pat = re.compile('''
            (
            [a-zA-Z\*]*
            (?<!\d)
            \*
            (?!\d)
            [a-zA-Z\*]*
            )+           
          ''', re.VERBOSE) 
regex_pat.findall(text)
# ['***', 'star*', 'st*r', '**m', '**'] The last two matches are no good.

显然,当正则表达式出现负面预测时,它需要退一步才能看出它是否可以获得匹配。我怎么能让负面看起来更贪婪或更具破坏性呢?

python regex
2个回答
1
投票

你可以用

(?<!\S)(?!\*+\d)[a-zA-Z]*\*[a-zA-Z*]*

regex demo

细节

  • (?<!\S) - 字符串或空格的开头
  • (?!\*+\d) - 如果在一个或多个星号之后有一个数字,则失败
  • [a-zA-Z]* - 0+个字母
  • \* - 星号
  • [a-zA-Z*]* - 0+字母或星号。

重点是在字符串的开头或空格后开始匹配,检查一个或多个星号后是否没有数字,然后匹配您需要的模式。

Python demo

import re
text = '''
    (A) Match these:
    *** star* st**r

    (B) Not these:
    800*m *4,500 

    (C) And not these:
    800**m **4,000
    '''
print(re.findall(r'(?<!\S)(?!\*+\d)[a-zA-Z]*\*[a-zA-Z*]*', text))
# => ['***', 'star*', 'st**r']

-1
投票

这个对我自己的问题的回答受到了WiktorStribiżew的评论的启发。它似乎工作。我在这里张贴它,以便更敏锐的眼睛可以告诉我任何缺陷。

regex_pat = re.compile('''
            (?<!\S)
            [a-zA-Z*]*            
            \*
            [a-zA-Z*]*
            (?!\S)
          ''', re.VERBOSE) 

我理解的逻辑是,前瞻和后视强制任何匹配成为一个完整的“单词”,从那里,你将不必再担心匹配中的数字,因为它们不是定义的角色的一部分无论如何都要匹配。

© www.soinside.com 2019 - 2024. All rights reserved.