在Python中提取嵌套正则表达式的所有匹配项

2024-05-13 14:50:28 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图解析满足python正则表达式的项列表

r'\A(("[\w\s]+"|\w+)\s+)*\Z'

也就是说,它是一个以空格分隔的列表,但引号内允许有空格。我想得到列表中的项目列表(即

^{pr2}$

部分。所以,举个例子

>>> parse('foo "bar baz" "bob" ')
['foo', '"bar baz"', '"bob"']

有没有什么好方法可以用pythonre做到这一点呢?在

很多事情不太管用。例如

>>> re.match(r'\A(("[\w\s]+"|\w+)\s+)*\Z', 'foo "bar baz" "bob" ').group(2)
'"bob"'

只返回它匹配的最后一个。另一方面

>>> re.findall(r'("[\w\s]+"|\w+)', 'foo "bar baz" "bob" ')
['foo', '"bar baz"', '"bob"']

但它也接受格式错误的表达式,比如

>>> re.findall(r'("[\w\s]+"|\w+)', 'foo "bar b-&&az" "bob" ')
['foo', 'bar', 'b', 'az', '" "', 'bob']

那么有没有任何方法可以使用原始正则表达式并获得与组2匹配的所有项?有点像

>>> re.match_multigroup(r'\A(("[\w\s]+"|\w+)\s+)*\Z', 'foo "bar baz" "bob" ').group(2)
['foo', '"bar baz"', '"bob"']
>>> re.match_multigroup(r'("[\w\s]+"|\w+)', 'foo "bar b-&&az" "bob" ')
None

编辑:在输出中保留引号是很重要的,因此我不想这样做

>>> re.match_multigroup(r'\A(("[\w\s]+"|\w+)\s+)*\Z', 'foo "bar baz" "bob" ').group(2)
['foo', 'bar baz', 'bob']

因为我不知道鲍勃是否被引用了。在


Tags: 项目方法re列表foomatchgroupbar
3条回答

这里有一个解决方案,它可以对不在引号内的任何空白进行拆分:

re.split('\s+(?=[^"]*(?:"[^"]*"[^"]*)*$)', target)

只有在刚刚匹配的空白前面有偶数个引号时,lookahead才会成功。如果文本中的引号部分可以包含转义引号,则可能需要更复杂的正则表达式,具体取决于转义的方式。在

好吧,最后我决定分两步来完成。在

首先,我检查表达式在语法上是否有效,然后将其分解为各个部分:

def parse(expr):
    if re.match(r'\A(("[\w\s]+"|\w+)\s+)*\Z', expr):
        return re.findall(r'("[\w\s]+"|\w+)', expr)

所以:

^{pr2}$

我有90%的把握这个方法对所有的字符串都适用,但是如果有人能有一个更通用的解决方案,我还是会感兴趣的,这对我来说似乎有点胡思乱想。在

感谢SilentGhost和Alan Moore的帮助。我以前不知道pythonscsv或regex lookaheads,了解一下这些可能会对我有所帮助。在

我不认为regex是这里合适的工具。尝试^{}模块:

>>> s = 'foo "bar baz" "bob" '
>>> for i in csv.reader([s], delimiter=' '):
    print(i)


['foo', 'bar baz', 'bob', '']

相关问题 更多 >