Python正则表达式替换单个换行符并忽略两个或多个换行符的序列

Python正则表达式替换单个换行符并忽略两个或多个换行符的序列,python,regex,python-3.x,Python,Regex,Python 3.x,我使用的是python 3.6到3.8 我试图用从文件读取的文本中的单个空格替换单个换行符的任何实例。我的目标是将段落压缩成单行文本,以便通过textwrap重新包装。由于textwrap只适用于单个段落,我需要一种简单的方法来检测/描绘段落,将它们压缩成一行文本似乎是最方便的方法。为了实现这一点,序列中两个或多个换行符的任何实例都定义了段落边界,应该单独处理 我的第一次尝试是使用lookahead/lookback断言来坚持我替换的任何新行都不受其他新行的限制: re.sub(r'(?<

我使用的是python 3.6到3.8

我试图用从文件读取的文本中的单个空格替换单个换行符的任何实例。我的目标是将段落压缩成单行文本,以便通过
textwrap
重新包装。由于
textwrap
只适用于单个段落,我需要一种简单的方法来检测/描绘段落,将它们压缩成一行文本似乎是最方便的方法。为了实现这一点,序列中两个或多个换行符的任何实例都定义了段落边界,应该单独处理

我的第一次尝试是使用lookahead/lookback断言来坚持我替换的任何新行都不受其他新行的限制:

re.sub(r'(?<!\n)\n(?!\n)', ' ', input_text)
import re
text = "This is some sample text beginning with a short paragraph.\n\nThis second paragraph is long enough to be split across lines, so it contains\na single newline in the middle.\n \nThis third paragraph has an unusual separator before it; a newline followed by\na space followed by another newline. It's a special case that needs to be\nhandled."
print( re.sub(r'([^\S\n]*\n(?:[^\S\n]*\n)+[^\S\n]*)|[^\S\n]*\n[^\S\n]*', lambda x: x.group(1) or ' ', text) )
要做到这一点,我需要一种方法来表达unicode中的“
\s
,除了
\n
”,我认为这是不存在的。我在百灵鸟上尝试了
[\s!\n]
,奇怪的是,它似乎在3.6.5和3.8.0中做了正确的事情。尽管事实上,
在任何一个版本的字符集中都没有记录的效果,
re.escape()
的文档明确指出,从3.7开始,
不再由该方法转义,因为它不是特殊字符

# this appears to work, but the docs say it shouldn't
re.sub(r'(?<!\n)\n(?!\n)', ' ', re.sub(r'\n[\s!\n]\n', '\n\n', input_text))
#这似乎有效,但医生说不应该
关于sub(r’(?)?

假设不支持最后一个,我还缺少什么方法?

您可以捕获出现的双换行和多换行,以便在匹配时保留它们,并仅匹配所有其他换行:

re.sub(r'(?<!\n)\n(?!\n)', ' ', input_text)
import re
text = "This is some sample text beginning with a short paragraph.\n\nThis second paragraph is long enough to be split across lines, so it contains\na single newline in the middle.\n \nThis third paragraph has an unusual separator before it; a newline followed by\na space followed by another newline. It's a special case that needs to be\nhandled."
print( re.sub(r'([^\S\n]*\n(?:[^\S\n]*\n)+[^\S\n]*)|[^\S\n]*\n[^\S\n]*', lambda x: x.group(1) or ' ', text) )

详细信息

  • ([^\S\n]*\n(?[^\S\n]*\n)+[^\S\n]*)
    -第1组:0+除换行符以外的空格,一个换行符,然后是0+除换行符和换行符以外的空格的1个或多个(因此,至少有两个换行符匹配),然后是0+除换行符以外的空格
  • |
    -或
  • [^\S\n]*\n[^\S\n]*
    -0+除换行符以外的空白、换行符以及0+除换行符以外的空白

替换为
lambda x:x.group(1)或“”
:如果组1匹配,则不应进行替换,否则,请用空格替换。

能否提供文本示例以便我们处理?能否为您的问题添加一个小文本示例?能否使用
(?把它算作去掉多余空格的奖励?问题中已经有了示例文本。@MonkeyZeus:这也可以将两个以上的换行压缩为两个。谢谢,这很有效。您还识别了“\s except\n”的正确表达式对我来说,这修复了我的最后一个示例:
re.sub(r')(?
import re
text = "This is some sample text beginning with a short paragraph.\n\nThis second paragraph is long enough to be split across lines, so it contains\na single newline in the middle.\n \nThis third paragraph has an unusual separator before it; a newline followed by\na space followed by another newline. It's a special case that needs to be\nhandled."
print( re.sub(r'([^\S\n]*\n(?:[^\S\n]*\n)+[^\S\n]*)|[^\S\n]*\n[^\S\n]*', lambda x: x.group(1) or ' ', text) )