删除字符串中的重复换行符

时间:2014-02-03 19:30:12

标签: python regex line-endings

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

我正在尝试将所有这些内容更改为\r\n,并删除连续的换行符。从理论上讲,这很容易,并且有很多非常简单的正则表达式should work

但实际上,

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不匹配?

3 个答案:

答案 0 :(得分: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>

答案 1 :(得分: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>

N.B:

以下正则表达式:

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

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

HTH

答案 2 :(得分:0)

事实证明问题是当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()