-1

我正在使用https://github.com/mrabarnett/mrab-regex(通过pip install regex,但在这里遇到了失败:

pattern_string =  r'''
        (?&N)
        ^ \W*? ENTRY              \W* (?P<entries>    (?&Range)    )     (?&N)

        (?(DEFINE)
             (?P<Decimal>
                 [ ]*? \d+ (?:[.,] \d+)? [ ]*?
             )
             (?P<Range>
                 (?&Decimal) - (?&Decimal) | (?&Decimal)
                 #(?&d) (?: - (?&d))?
             )
             (?P<N>
                 [\s\S]*?
             )
        )
    '''

flags = regex.MULTILINE | regex.VERBOSE  #| regex.DOTALL  | regex.V1 #| regex.IGNORECASE | regex.UNICODE

pattern = regex.compile(pattern_string, flags=flags)

bk2 = f'''
ENTRY: 0.0975 - 0.101
'''.strip()
match = pattern.match('ENTRY: 0.0975 - 0.101')
match.groupdict()

给出:

{'entries': '0.0975', 'Decimal': None, 'Range': None, 'N': None}

它错过了第二个值。

> pip show regex
Name: regex
Version: 2022.1.18
Summary: Alternative regular expression module, to replace re.
Home-page: https://github.com/mrabarnett/mrab-regex
Author: Matthew Barnett
Author-email: regex@mrabarnett.plus.com
License: Apache Software License
Location: ...
Requires:
Required-by:

> python --version
Python 3.10.0
4

1 回答 1

2

问题是你在组模式中定义的空间Decimal被消耗了,DEFINE模式是原子的,所以虽然最后[ ]*?一部分是惰性的,可以匹配零次,但一旦匹配,就没有回头路了。如果您将Decimal模式放入一个原子组并比较两个模式,您可以检查这一点,参见。这个正则表达式演示这个正则表达式演示(?mx)^\W*?ENTRY\W*(?P<entries>(?>[ ]*? \d+ (?:[.,] \d+)? [ ]*?) - (?>[ ]*? \d+ (?:[.,] \d+)? [ ]*?) | (?>[ ]*? \d+ (?:[.,] \d+)? [ ]*?))公开与您的正则表达式相同的行为DEFINE,同时(?mx)^\W*?ENTRY\W*(?P<entries>[ ]*? \d+ (?:[.,] \d+)? [ ]*? - [ ]*? \d+ (?:[.,] \d+)? [ ]*? | [ ]*? \d+ (?:[.,] \d+)? [ ]*?)正确找到匹配项。

最简单的解决方法是将可选空间模式移动到Range组模式中。

您可能想在此处介绍其他一些小的增强功能:

  • 由于您只对捕获的子字符串感兴趣,因此不需要regex.matchN组模式 ( [\s\S]*?) 一起使用,您可以使用regex.search并从正则表达式中删除N模式
  • 您不需要为a|a-b类似模式使用组,您可以使用更有效的可选非捕获组方法,a(?:-b)?.

所以,正则表达式看起来像

^ \W* ENTRY              \W* (?P<entries>    (?&Range)    ) 
(?(DEFINE)
    (?P<Decimal>
        \d+ (?:[.,] \d+)?
    )
    (?P<Range>
        (?&Decimal)(?:\ *-\ *(?&Decimal))*
    )
)

​查看正则表达式演示

请参阅Python 演示

import regex
pattern_string =  r'''
        ^ \W* ENTRY              \W* (?P<entries>    (?&Range)    )

        (?(DEFINE)
             (?P<Decimal>
                 \d+ (?:[.,] \d+)?
             )
             (?P<Range>
                 (?&Decimal)(?:\ *-\ *(?&Decimal))?
             )
        )
    '''

flags = regex.MULTILINE | regex.VERBOSE
pattern = regex.compile(pattern_string, flags=flags)

bk2 = f'''
ENTRY: 0.0975 - 0.101
'''.strip()

match = pattern.search('ENTRY: 0.0975 - 0.101')

print(match.groupdict())

输出:

{'entries': '0.0975 - 0.101', 'Decimal': None, 'Range': None}
于 2022-02-10T10:07:34.803 回答