【问题标题】:Failure in finding '-<' substring using regex使用正则表达式查找“​​-<”子字符串失败
【发布时间】:2013-04-24 15:04:12
【问题描述】:

以下是目标字符串。

July 17, 2007 –<br> September 25, 2009 <br> June 2007 - July 2010

我正在尝试在&lt;br&gt; 标记之前添加一个换行符,该标记不跟随-。因此,结果字符串应该是:

July 17, 2007 –<br> September 25, 2009 \n<br> June 2007 - July 2010

我尝试了以下正则表达式无济于事。

re.sub(r'([^-])(\s*<br)',r'\1\n\2', astring)

给我

July 17, 2007 –\n<br> September 25, 2009\n <br> June 2007 - July 2010

解决办法是什么?

更新:

我实际上并没有使用正则表达式解析 HTML。我知道 HTML + RegEx 组合会让我发疯。 我已经在使用 lxml 来解析 HTML。 但是,我无法理解的是为什么正则表达式无法捕获 -\s*&lt; 模式。

【问题讨论】:

    标签: regex python-3.x


    【解决方案1】:

    文本中的破折号是EN DASH U+2013,这就是([^-]) 匹配EN DASH 并发生替换的原因。

    您需要将字符添加到您的字符类中,并将\s* 移动到第一个捕获组,并将\s 添加到取反的字符类中以使其按您的意愿工作:

    re.sub(r'([^\s–-]\s*)(<br)',r'\1\n\2', astring)
    

    请注意,虽然上面的代码有效,但它不可维护 - 因为很难注意到字符类中的 EN DASH

    Python 3.3 及以上,添加了\u\U Unicode 转义序列。您可以这样指定您的正则表达式:

    re.sub(r'([^\s\u2013-]\s*)(<br)',r'\1\n\2', astring)
    

    \u2013 是什么可能不太清楚,但至少,代码的读者不会被绊倒。

    对于 Python 3.2 及以下版本,您可以使用普通的文字字符串而不是原始文字字符串语法来实现正则表达式的相同效果。

    re.sub('([^\\s\u2013-]\\s*)(<br)',r'\1\n\2', astring)
    

    从技术上讲,由于 Python 解析文字字符串的方式(如果 \ 没有形成有效的转义序列,则保留它),'([^\s\u2013-]\s*)(&lt;br)' 也可以工作(比较 \\s\s),但我加倍逃跑只是为了安全。

    【讨论】:

    • 这每次都让我着迷,该死!我决定先将所有 EN DASH 替换为连字符 -,而不是使用这两个字符。然后,我只需要在正则表达式中使用连字符 -
    • 当我在-&lt;br&gt; 之间有空格时,这不起作用。显然,[^-] 也会包含空格,因此会破坏正则表达式。
    • 我因此改进了正则表达式 - ([^-\s]\s*)(&lt;br)。它似乎已经解决了这个问题。告诉我这是否有问题。
    • @MisterBhoot:看来我们找到了相同的解决方案。
    • @nhahtdh - 是的。无论如何,感谢您的快速努力。
    【解决方案2】:

    字符串中的 和正则表达式中的- 不是同一个字符。试试

    re.sub(r'([^–])(\s*<br)',r'\1\n\2', astring)
    

    【讨论】:

    • 虽然我已经从您的回答中理解了这个问题(这是我的提要中第一个出现的问题),但@nhahtdh 的回答更全面。我会接受他的回答。
    猜你喜欢
    • 1970-01-01
    • 2012-12-01
    • 1970-01-01
    • 2016-05-16
    • 2012-05-12
    • 2014-11-26
    • 1970-01-01
    相关资源
    最近更新 更多