在环视中引用命名组(Python 2.x)

时间:2016-09-12 18:33:27

标签: python regex regex-lookarounds regex-greedy

我有一个匹配多个键/值对的模式,键/值字符串可以用任何字符分隔,然后键/值组也可以分隔,只是不是同一个角色

我想出了如何允许动态分隔符,并限制使用两次相同的分隔符。 EG:

\w+(?P<kv_delim>[:;|])\d+(?P<g_delim>(?!(?P=kv_delim))[:;|])\w(?P=kv_delim)\d(?P=g_delim)?

You can view the regex101.com example here。并且效果很好,当在正面观察中使用两个命名组中的任何一个时,问题就出现了。

让我们说字符串是

  

foo:1;r:2

&#34;键/值分隔符&#34; (命名组:kv_delim)是:,然后是&#34;组分隔符&#34; (命名组:grp_delim)是;

我尝试做的是动态匹配:;,然后在环顾陈述中查找foo<kv_delim>bar<kv_delim>

如果我对分隔符进行硬编码(在环顾中),you can see it works。但是,如果我尝试在环视声明you can see it throws errors中引用命名组kv_delim。我收到错误:

  

在lookbehind断言中不允许使用子模式引用

我的屁股是什么?

有人有办法让这项工作吗?

谢谢!

1 个答案:

答案 0 :(得分:0)

总结已经说过的内容:关键是当你在设计时将反馈引入must be fixed-width时,模式的长度是未知的。较新的PyPi regex module对于lookbehind长度没有限制,因此,目前的解决方法是将此模块与正则表达式一起使用:

>>> import regex
>>> s = "foo:1;r:2"
>>> rx = r"\w+(?P<kv_delim>[:;|])\d+(?P<g_delim>(?!(?P=kv_delim))[:;|])\w(?P=kv_delim)\d(?P=g_delim)?"
>>> print(regex.findall(rx, s))
[(':', ';')]
>>> print([m.group() for m in regex.finditer(rx, s)])
['foo:1;r:2']
>>>