python正则去除换行符,关于python:用于删除换行符的正则表达式

我是Python的新手,我遇到了正则表达式问题。 我正在尝试删除文本文件中每行末尾的换行符,但前提是它跟在小写字母后面,即[a-z]。 如果该行的结尾以小写字母结尾,我想用空格替换换行符/换行符。

这是我到目前为止所得到的:

import re

import sys

textout = open("output.txt","w")

textblock = open(sys.argv[1]).read()

textout.write(re.sub("[a-z]\z","[a-z]", textblock, re.MULTILINE) )

textout.close()

如果RE中没有$且没有^,则不需要标记re.MULTILINE

尝试

re.sub(r"(?<=[a-z])

?

","", textblock)

\Z仅匹配字符串末尾,在最后一个换行符之后,所以它绝对不是你需要的。 Python正则表达式引擎无法识别\Z。

(?<=[a-z])是一个正向的lookbehind断言,用于检查当前位置之前的字符是否为小写ASCII字符。只有这样,正则表达式引擎才会尝试匹配换行符。

此外,始终使用带有正则表达式的原始字符串。使反斜杠更容易处理。

你是对的! ;)

我会用[

]+替换?以命中单个。

@ThiefMaster,它也会删除空行,顺便说一句

@ThiefMaster:周围仍然有Mac使用,并且Python上运行吗?我以为Apple放弃了OS X的行结尾,但我可能完全错了。

希望不是..但你永远不知道有什么糟糕的文件 - 有太多的文件包含和的混合所以我希望一些文件仍然存在。

所以[

]{1,2}会根据我的情况做得更好:(

|

?),其中的可能性是第三个被测试的可能性。

@eyquem:肯定是第二个:(?:

|

?),或者你可能偶然删除两个相邻的Unix换行符。

顺便说一句,这个RE绝对不需要原始字符串。而\Z匹配字符串的结尾,而不是更低

哦,是的。你的?:不需要。

@eyquem:使用原始字符串总是很好的做法。你知道哪些反斜杠逃脱是必要的,哪些不是?这只是消除了一个常见的错误来源。如果我不打算捕获其内容,我也总是喜欢非捕获括号。不仅仅是出于效率原因,而是为了清晰起见,并且因为一些Python正则表达式操作在捕获parens时表现得非常不同。关于\Z和\Z,你适合使用Python - 我发现Python没有实现Perl,.NET,PCRE等常用的行为。

@Tim Pietzcker我不喜欢表达"永远"真理的句子。 Personnaly,我宁愿不使用原始字符串:这迫使我理解我写的内容并记住我的理解。在正则表达式中没有那么多的逃避,我记得更常见的,另一个我验证。这是一个品味问题。我担心RE中使用raw-string会阻止新手真正理解正则表达式编译器对RE的解释。

作为一个替代答案,虽然它需要更多的行,但我认为以下可能更清楚,因为正则表达式更简单:

import re

import sys

with open(sys.argv[1]) as ifp:

with open("output.txt","w") as ofp:

for line in ifp:

if re.search('[a-z]$',line):

ofp.write(line.rstrip("

")+"")

else:

ofp.write(line)

...并且避免将整个文件加载到字符串中。如果你想使用更少的线条,但仍然避免积极的外观,你可以这样做:

import re

import sys

with open(sys.argv[1]) as ifp:

with open("output.txt","w") as ofp:

for line in ifp:

ofp.write(re.sub('(?m)([a-z])[

]+$','\\1 ',line))

正则表达式的部分是:

(?m) [开启多线匹配]

([a-z]) [将单个小写字符作为第一组匹配]

[

]+ [匹配一个或多个回车符或换行符,以涵盖,和]

$ [匹配字符串的结尾]

...如果匹配行,则小写字母和行结尾将替换为\\1,小写字母后跟空格。

一行ofp.write(re.sub("(?<=[a-z])(

|

?)","",line)而不是四行

@eyquem:当然,但我的观点是避免使用正面的lookbehind可能会使代码更具可读性,而且额外的三行可能是值得的......好吧,我还是会添加另一个版本。

我的观点是避免使用正面的lookbehind可能会使代码更具可读性

好。虽然,就个人而言,我发现它的可读性不高。这是一个品味问题。

在你的编辑中:

首先,(?m)不是必需的,因为对于ifp中的行:一次选择一行,因此每行的字符串末尾只有一个换行符

其次,$放置时,没有效用,因为它总是匹配字符串行的结尾。

无论如何,采用你的观点,我发现了两种方式来避免看到后面的断言:

with open(sys.argv[1]) as ifp:

with open("output.txt","w") as ofp:

for line in ifp:

ante_newline,lower_last = re.match('(.*?([a-z])?$)',line).groups()

ofp.write(ante_newline+' ' if lower_last else line)

with open(sys.argv[1]) as ifp:

with open("output.txt","w") as ofp:

for line in ifp:

ofp.write(line.strip('

')+' ' if re.search('[a-z]$',line) else line)

第二个更好:只有一行,一个简单的匹配测试,不需要groups(),自然逻辑

编辑:哦,我意识到第二个代码只是你的第一个代码重写在一行,Longair

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值