【问题标题】:Remove duplicate linebreaks in a string删除字符串中的重复换行符
【发布时间】:2014-02-03 19:30:12
【问题描述】:

我有一些文件可以使用\r\n\r\n 作为它们的换行模式。

我正在尝试将它们全部更改为\r\n,并删除连续的换行符。理论上,这很容易,任何数量的very simple regexes 都应该可以工作。

但在实践中,

text = re.sub(
    reg_exp,
    r'\r\n',
    text)

在这个字符串上(显示行结束字符),

<ul>␍␊
␍␊
<li><a href="#">link</a></li>␍␊
␍␊
<li><a href="#">link</a></li>␍␊
<li><a href="#">link</a></li>␍␊
␍␊
<li><a href="#">link</a></li>␍␊
␍␊
</ul>␍␊
  • reg_exp = r'[\r\n]{2,}',制作

    <ul>␍
    ␍␊
        <li><a href="#">link</a></li>␍
    ␍␊
        <li><a href="#">link</a></li>␍␊
        <li><a href="#">link</a></li>␍
    ␍␊
        <li><a href="#">link</a></li>␍
    ␍␊
    </ul>␍␊
    
  • reg_exp = r'[\r\n]+',制作

    <ul>␍
    ␍␊
       <li><a href="#">link</a></li>␍
    ␍␊
       <li><a href="#">link</a></li>␍
    ␍␊
       <li><a href="#">link</a></li>␍
    ␍␊
       <li><a href="#">link</a></li>␍
    ␍␊
    </ul>␍
    ␍␊
    

我不知道为什么。

我的正则表达式是否由于某种原因与 \r 不匹配?

【问题讨论】:

    标签: python regex line-endings


    【解决方案1】:

    好吧,我不确定您是否正确复制/粘贴了示例字符串,但是\r\n 字符串的每次出现之间都有一个额外的字符,所以基本上是以下正则表达式:

    re.sub(r'(\r\n.?)+', r'\r\n', text)
    

    将删除以下任何一项:

    \r\n\r\n
    \r\n \r\n
    \r\n\n\r\n
    \r\n\r\n\r\n
    \r\n \r\n \r\n
    \r\n\r\n \r\n
    \r\n \r\n\r\n
    ...
    

    全面测试:

    >>> text =  """<ul>\r\n \r\n <li><a href="#">link</a></li>\r\n \r\n <li><a href="#">link</a></li>\r\n <li><a href="#">link</a></li>\r\n \r\n <li><a href="#">link</a></li>\r\n \r\n </ul>\r\n"""
    >>> print text
    <ul>
    
     <li><a href="#">link</a></li>
    
     <li><a href="#">link</a></li>
     <li><a href="#">link</a></li>
    
     <li><a href="#">link</a></li>
    
     </ul>
    >>> print re.sub(r'(\r\n.?)+', r'\r\n', text).__repr__()
    '<ul>\r\n<li><a href="#">link</a></li>\r\n<li><a href="#">link</a></li>\r\n<li><a href="#">link</a></li>\r\n<li><a href="#">link</a></li>\r\n</ul>\r\n'
    >>> print re.sub(r'(\r\n.?)+', r'\r\n', text)
    <ul>
    <li><a href="#">link</a></li>
    <li><a href="#">link</a></li>
    <li><a href="#">link</a></li>
    <li><a href="#">link</a></li>
    </ul>
    

    注:

    以下正则表达式:

    print re.sub(r'([\r\n]+.?)+', r'\r\n', text)
    

    也可以,并且只能支持\n 字符串。

    HTH

    【讨论】:

      【解决方案2】:

      您还可以在字符串上使用 splitlines() 并使用 '\r\n' 连接行

      >>> text = '<ul>\r\n \r\n <li><a href="#">link</a></li>\r\n \r\n <li><a href="#">link</a></li>\r\n <li><a href="#">link</a></li>\r\n \r\n <li><a href="#">link</a></li>\r\n \r\n </ul>\r\n\r \n'
      >>> print '\r\n'.join([x for x in text.splitlines() if x.strip()])
      <ul>
       <li><a href="#">link</a></li>
       <li><a href="#">link</a></li>
       <li><a href="#">link</a></li>
       <li><a href="#">link</a></li>
       </ul>
      

      【讨论】:

        【解决方案3】:

        原来问题出在 Python 将字符串写回 Windows 文件系统时。它对如何处理行尾做出了一些意想不到的决定。具体来说,它决定:

        • \r 应该写成\r
        • \n 应该写成 \r\n(什么!?)

        zmoLouis 的答案都可以在 Python 控制台中使用,事实证明,问题中的代码也是如此。

        为了完整起见,这就是write() 的样子:

        with open(file_name, 'r+') as f:
            text = f.read()
        
            # text = re.sub(...)
        
            f.seek(0)
            f.write(text)
            f.truncate()
        

        【讨论】:

          猜你喜欢
          • 2014-07-23
          • 2014-12-16
          • 2013-11-12
          • 2021-03-20
          • 2020-03-30
          • 1970-01-01
          • 2019-09-28
          • 2014-01-27
          • 1970-01-01
          相关资源
          最近更新 更多