-1

我需要一个正则表达式来匹配a,ba;b.

我不能写a|b|a;b,因为ab包含命名组,如果我尝试这样做,我会得到一个例外: 将组名“a”重新定义为组 8;在第 60 位是第 3 组

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

你会如何解决这个问题?re图书馆有可能吗?我听说还有一个图书馆叫pyparsing. 那会更适合这个问题吗?


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

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

工作正则表达式,除了它与测试程序[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
4

3 回答 3

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'
于 2019-12-27T15:05:57.793 回答
1

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

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

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

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

我没有为整数值提供任何有意义的名称,因为它们可能会根据尾随的字母字符而有所不同(并且长度也可能大于 1 位)。

对于未来的正则表达式开发工作,https://regex101.com是一个很好的交互式页面,用于解决 re kinks。

于 2019-12-27T14:46:54.937 回答
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:没有做太多的测试。希望能帮助到你。

于 2019-12-25T20:13:20.777 回答