python regex:带分隔符的一个或两个

时间:2019-12-25 16:33:08

标签: python regex pyparsing

我需要一个正则表达式来匹配aba;b

我无法写a|b|a;b,因为ab包含命名组,如果我尝试这样做,则会出现异常: 将组名“ a”重新定义为组8;是第3组的第60名

a;?b也不起作用,因为ab必须不匹配。

您将如何解决? re库是否有可能? 我听说还有一个名为pyparsing的图书馆。会更适合这个问题吗?


背景:这是this one的后续问题。 因为似乎无法通过urwid或curses中的颜色代码,所以我试图对从git中获得的颜色代码进行解码,以便urwid可以重新编码这些颜色。

为避免复制和粘贴出现问题,我在以下正则表达式中省略了前导控制字符:

有效的正则表达式,但与a test program中使用的[1m(粗体)不匹配:

reo_color_code = re.compile(
    r'\['
    r'((?P<series>[01]);)?'
    r'((?P<fgbg>[34])(?P<color>[0-7]))?'
    r'm'
)

不编译正则表达式:

reo_color_code = re.compile(
    r'\['
    r'('
        r'((?P<series>[01]))'
        r'|'
        r'((?P<fgbg>[34])(?P<color>[0-7]))'
        r'|'
        r'((?P<series>[01]));((?P<fgbg>[34])(?P<color>[0-7]))'
    r')'
    r'm'
)

引发异常

re.error: redefinition of group name 'series' as group 8; was group 3 at position 60

3 个答案:

答案 0 :(得分:1)

在这种情况下,我不会尝试构建单个正则表达式来解决整个问题,相反,我将实现如下所示的方法(也使用re但在不同的级别) :

def get_info(s):
    if s.startswith('[') and s.endswith('m'):
        p = s[1:-1]
        if ';' in p:
            m = re.match('^([01]);([34])([0-7])$', p)
        else:
            m = re.match('^([01])$|^([34])([0-7])$', p)
        if m:
            return tuple(m.groups())
    return None, None, None

您可以像这样使用它:

>>> serie, fgbg, color = get_info('[1;37m')
>>> serie, fgbg, color
('1', '3', '7')

PS:没有做太多测试。希望对您有所帮助。

答案 1 :(得分:1)

这是用于破解ANSI终端序列的更通用的正则表达式:

\[(\d+)(?:;(\d+))?([a-z])

如果您想按名称访问组,请使用以下命令:

\[(?P<d1>\d+)(?:;(?P<d2>\d+))?(?P<trailing>[a-z])

我没有给整数值提供任何有意义的名称,因为它们会随尾随的字母字符而变化(也可以大于1位数字)。

对于以后的正则表达式开发工作,https://regex101.com是一个很棒的交互式页面,可以帮助您解决所有问题。

答案 2 :(得分:1)

自从您询问有关pyparsing的内容后,pyparsing解析器的外观将是:

import pyparsing as pp

integer = pp.pyparsing_common.integer
ansi_expr = ("[" 
             + integer("d1") 
             + pp.Optional(';' + integer("d2")) 
             + pp.oneOf(list(pp.alphas.lower()))("trailing"))

ansi_expr.runTests("""\
    [1m
    [23;34z
    """)

具有测试输出:

[1m
['[', 1, 'm']
- d1: 1
- trailing: 'm'

[23;34z
['[', 23, ';', 34, 'z']
- d1: 23
- d2: 34
- trailing: 'z'