使用Python的re模块转换字符串

2 投票
3 回答
660 浏览
提问于 2025-04-17 07:45

我有一行字符串:

>>> line = "  abc\n  def\n\n  ghi\n  jkl"
>>> print line
  abc
  def

  ghi
  jkl

我想把它转换成 "abcdef\n\n ghijkl",像这样:

>>> print "  abcdef\n\n  ghijkl"
  abcdef

  ghijkl

我试过用 Python 的 re 模块,写了类似这样的代码:

re.sub('(?P<word1>[^\n\s])\n\s*(?P<word2>[^\n\s])', '\g<word1>\g<word2>', line)

但是我得到了这个结果:

>>> re.sub('(?P<word1>[^\n\s])\n\s*(?P<word2>[^\n\s])', '\g<word1>\g<word2>', line)
Out: '  abcdefghijkl'

我觉得 \n\s* 这一部分也匹配到了 \n\n。有没有人能告诉我我哪里出错了?

3 个回答

0

如果你使用 \S,可以让正则表达式更简单,因为它可以匹配任何不是空格的字符。

>>> import re
>>> line = "  abc\n  def\n\n  ghi\n  jkl"
>>> print re.sub(r'(\S+)\n\s*(\S+)', r'\1\2', line)
  abcdef

  ghijkl

不过,你的正则表达式之所以不工作的原因是因为你的 <word1><word2> 组只匹配了一个字符(也就是说,它们没有使用 +)。只要做这个简单的修改,你的正则表达式就能产生正确的结果:

>>> print re.sub(r'(?P<word1>[^\n\s]+)\n\s*(?P<word2>[^\n\s]+)', r'\g<word1>\g<word2>', line)
  abcdef

  ghijkl
0

试试这个,

line = "  abc\n  def\n\n  ghi\n  jkl"
print re.sub(r'\n(?!\n)\s*', '', line)

它会输出,

abcdef
ghijkl

这段代码的意思是:“把换行符后面跟着的、但不是换行符的空格替换成什么都没有。”

更新:这是一个更好的版本

>>>  re.sub(r'([^\n])\n(?!\n)\s*', r'\1', line)
'  abcdef\n\n  ghijkl'

它的输出正好和你在第一条帖子里说的一样。

4

\s 是用来匹配空格、\t(制表符)、\n(换行符),还有一些其他的空白字符(这取决于你使用的正则表达式工具)。

所以,如果你只想替换单个换行符加上空格或制表符,可以使用这个:

newline = re.sub(r"(?<!\n)\n[ \t]*(?!\n)", "", line)

解释:

(?<!\n) # Assert that the previous character isn't a newline
\n      # Match a newline
[ \t]*  # Match any number of spaces/tabs
(?!\n)  # Assert that the next character isn't a newline

在 Python 中:

>>> line = "  abc\n  def\n\n  ghi\n  jkl"
>>> newline = re.sub(r"(?<!\n)\n[ \t]*(?!\n)", "", line)
>>> print newline
  abcdef

  ghijkl

撰写回答