python正则去除换⾏符,关于python:⽤于删除换⾏符的正则
表达式
我是Python的新⼿,我遇到了正则表达式问题。 我正在尝试删除⽂本⽂件中每⾏末尾的换⾏符,但前提是它跟在⼩写字母后⾯,即[a-z]。如果该⾏的结尾以⼩写字母结尾,我想⽤空格替换换⾏符/换⾏符。
这是我到⽬前为⽌所得到的:
import re
import sys
textout = open("","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:肯定是第⼆个:(?:
python正则表达式不包含|
),或者你可能偶然删除两个相邻的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("","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("","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("","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("","w") as ofp:
for line in ifp:
ofp.write(line.strip('
')+' ' if re.search('[a-z]$',line) else line)
第⼆个更好:只有⼀⾏,⼀个简单的匹配测试,不需要groups(),⾃然逻辑
编辑:哦,我意识到第⼆个代码只是你的第⼀个代码重写在⼀⾏,Longair

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。