在 Python 中删除前导/结尾和内部多个空格,但不删除制表符、换行符或返回字符

NFB*_*NFB 2 python whitespace scrapy

Python 删除字符串中的所有空格问题的答案显示了从 Python 中的字符串中分别删除前导/结尾、重复和所有空格的不同方法。但是 strip() 会删除制表符和换行符,而 lstrip() 只会影响前导空格。使用 .join(sentence.split()) 的解决方案似乎也删除了 Unicode 空白字符。

假设我有一个字符串,在本例中是使用 Scrapy 从网站上抓取的,如下所示:

['\n                        \n                    ',
         '\n                        ',
         'Some text',
         ' and some more text\n',
  ' and on another a line some more text', '
                ']
Run Code Online (Sandbox Code Playgroud)

当我在其他上下文中使用文本时,换行符会保留文本的格式,但所有额外的空间都很麻烦。如何删除所有前导、结尾和重复的内部空格,同时保留换行符(除了任何 \r 或 \t 字符,如果有的话)?

我想要的结果(在加入各个字符串之后)将是:

['\n\n\nSome text and some more text\nand on another line some more text']
Run Code Online (Sandbox Code Playgroud)

没有提供示例代码,因为到目前为止我所尝试的只是上面引用的页面上的建议,这得到了我试图避免的结果。

Jea*_*bre 5

在这种情况下,str.strip()不会对您有帮助(即使您用作" "参数,因为它不会删除内部的空格,只会删除字符串的开头/结尾处的空格,并且它也会删除之前的单个空格"and"

相反,使用正则表达式从字符串中删除 2 个或更多空格:

l= ['\n                        \n                    ',
         '\n                        ',
         'Some text',
         ' and some more text\n',
  ' and on another a line some more text']

import re

result = "".join([re.sub("  +","",x) for x in l])

print(repr(result))
Run Code Online (Sandbox Code Playgroud)

印刷:

'\n\n\nSome text and some more text\n and on another a line some more text'
Run Code Online (Sandbox Code Playgroud)

编辑:如果我们将正则表达式应用于每一行,\n在某些情况下我们无法检测到,正如您所指出的。因此,替代且更复杂的解决方案是在应用正则表达式之前连接字符串,并应用更复杂的正则表达式(请注意,我更改了字符串的测试列表以添加更多极端情况):

l= ['\n                        \n                    ',
         '\n                        ',
         'Some text',
         ' and some more text \n',
  '\n and on another a line some more text ']

import re

result = re.sub("(^ |(?<=\n) |  +| (?=\n)| $)","","".join(l))

print(repr(result))
Run Code Online (Sandbox Code Playgroud)

印刷:

'\n\n\nSome text and some more text\n\nand on another a line some more text'
Run Code Online (Sandbox Code Playgroud)

正则表达式中有 5 个案例将被删除:

  • 以一个空格开始
  • 换行符后面有空格
  • 2 个或更多空格
  • 空格后跟换行符
  • 以一个空格结尾

事后思考:看起来(而且确实)很复杂。毕竟有一个非正则表达式解决方案可以给出完全相同的结果(如果单词之间没有多个空格):

result = "\n".join([x.strip(" ") for x in "".join(l).split("\n")])
print(repr(result))
Run Code Online (Sandbox Code Playgroud)

只需连接字符串,然后根据换行符拆分,应用stripwith" "作为参数以保留制表符,然后根据换行符再次连接。

链接 withre.sub(" +"," ",x.strip(" "))来处理单词之间可能存在的双空格:

result = "\n".join([re.sub("  +"," ",x.strip(" ")) for x in "".join(l).split("\n")])
Run Code Online (Sandbox Code Playgroud)