Regexp:过滤由相同模式包围的模式

时间:2017-10-03 09:56:07

标签: python regex

拥有以下布局的文本示例......

<​text text <​text text> text text>

<​text text> <text text text <text ​text text>

...我需要抓住<​enclosed parts​>突出显示。

使用延迟量词,正则表达式<.*?>返回...

  

&lt; text text&lt; text text&gt; text text&gt;

     

&lt;文字文字&gt; &lt;文字文字文字&lt;文字文字&gt;

...错过右上部分,错误地包括中间底部。我也用<.[^<]*?>尝试了它,它在2 -nd 行上做到了,但在1 -st 上错过了左右两部分:

  

&lt;文字文字&lt;文字文字&gt; 文字文字&gt;

     

&lt;文字文字&gt; &lt;文字文字文字&lt;文字文字&gt;

正则表达式如何看待<​work as above​>

2 个答案:

答案 0 :(得分:1)

grep -Pzo "(?:<(?:[^<]|[<].*[>])*>)*" /tmp/test1
<​text text <​text text> text text><​text text><text ​text text>

$ cat / tmp / test1

<​text text <​text text> text text>

<​text text> <text text text <text ​text text>

或作为替代放弃多线处理

$ grep -Po "(?:<(?:[^<]|[<].*[>])*>)*" /tmp/test1
<​text text <​text text> text text>
<​text text>
<text ​text text>

答案 1 :(得分:0)

匹配平衡括号(或其他符合和嵌入的符号)是正则表达式原则上无法做到的事情的经典案例。这是一个众所周知的数学结果,并且无可争议(例如,请参阅exercise 1 here或查看this question)。当然,您可以编写一个可以处理一个级别的嵌入或两个嵌入级别的正则表达式,但正则表达式语言根本无法处理不受限制的级别数。 / p>

事实是,今天的&#34; perl风格的正则表达式&#34;有足够的扩展(例如\1后置替换)可以一起攻击某些东西,某些非常规(因为它们被称为)任务...不确定是否你的是你的。但它会变得丑陋而复杂,而且你冒着一个风险,它会在输入错误的情况下爆炸到指数运行时间。

我建议您放置正则表达式,并编写一个循环来迭代文本中的字符并计算嵌入级别。简单,可读,并且在你的字符串上一次性完成,没有回溯:

starts = []
for i in range(len(text)):
if text[i] == "<":
    starts.append(i)
elif text[i] == ">" and len(starts) > 0:
    print(text[starts[-1]:i+1])
    starts.pop()