【问题标题】:Python re.findall non-greedy resultPython re.findall 非贪婪结果
【发布时间】:2017-07-13 21:41:57
【问题描述】:

我正在尝试使用以下代码仅获取“Text3”部分:

import re
stringtotest = "begin:Text1<wrong>Text2<wrong>Text3<right>Text4<wrong>"
right = re.findall("<wrong>(.+?)<right>",stringtotest)
>>> right
['Text2<wrong>Text3']

为什么 Python 也会给我 Text2?如何告诉他我只想要最近的“错误”之后的部分?谢谢你。

【问题讨论】:

  • 这个问题与贪婪与非贪婪关系不大,因为即使是非贪婪匹配也无法产生预期的结果。提问者使用的是惰性匹配,它的攻击性更小。
  • 你说得对。
  • 抱歉,我是 Python 新手。如果我有 stringtotest = "begin\r\nText1\r\n\r\nText2\r\nsome more text\r\n\r\nText3\r\n\r\ nText4\r\n" 我怎样才能只得到 之前的部分?

标签: python regex findall non-greedy


【解决方案1】:

. 匹配任何内容。您可以使用否定字符类来限制匹配:

<wrong>([^<]+?)<right>

如果你想得到没有外部标签的中间部分,使用前瞻和后瞻来断言标签的位置:

(?<=<wrong>)([^<]+?)(?=<right>)

【讨论】:

  • 你不应该在这里使用惰性匹配,因为贪婪匹配永远不会超过正确的“边界”。贪婪地它需要一步来匹配关闭&gt; 和打开&lt; 之间的字符,而懒惰地它自己检查每个字符。请注意,许多正则表达式引擎(虽然不确定是否支持 python)会在内部优化 [^&lt;]+&lt;(?&gt;[^&lt;]+)&lt; 以避免不必要的回溯。
  • 你说得对,我打算编辑它,但我认为保存 20 步对提问者来说并不重要。不过,对于其他观众来说,这是很好的信息,感谢您的评论。
【解决方案2】:
<wrong>((?:(?!<wrong>).)*)<right>

您可以使用基于否定前瞻的量词。参见演示。

https://regex101.com/r/8yUhDL/1

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-10-05
    • 2011-05-15
    • 2011-08-25
    • 1970-01-01
    • 1970-01-01
    • 2012-03-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多