用Python检测换行符

2024-09-24 16:34:41 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图用Python检测文件中的独立换行。该文件有一些独立的“LF”(即.\n)和一些“CRLF”(即.\r\n)组合,我正在尝试与独立的组合匹配。你知道吗

我以为这样行得通:

match = re.search('(?<!\r)\n', line)

其中line是循环通过的文件中的字符串。然而,背后的负面看法似乎并不奏效。你知道吗

以下是上下文的完整脚本:

import sys
import fileinput
import os
import os.path
import re

# Descriptions: iterates over files in source directory, removes whitespace characters and saves to destination directory.


print ('Source Directory:', str(sys.argv[1]))
print ('Destination Directory:', str(sys.argv[2]))

for i in os.listdir(sys.argv[1]):
    fullSource = (os.path.join(sys.argv[1], i))
    fullDestination = (os.path.join(sys.argv[2], i))
    newfile = open(fullDestination, "x")
    for line in fileinput.input(fullSource):
        matchObj = re.search('(?<!\r)\n', line)
        if matchObj:
            newfile.write(line.rstrip('\r\n'))
        else:
            newfile.write(line)
    newfile.close
    print ("created " + fullDestination)

结果是所有返回(CR和CRLF)都被删除。 我错过什么了吗?你知道吗


Tags: 文件pathinimportresearchossys
2条回答

好吧,这个结果并不奇怪。fileinput模块默认以文本模式打开文件,因此\r\n在单个\n中自动更改。因此正则表达式匹配每一行并删除所有的\n-这些\r已经被fileinput删除了。你知道吗

所以必须明确使用二进制打开模式。不幸的是,如果您使用python3.x(您的print语法所建议的),二进制模式将为您提供需要转换为字符串的字节。您的代码可能会变成:

import sys
import fileinput
import os
import os.path
import re

# Descriptions: iterates over files in source directory, removes whitespace characters and saves to destination directory.


print ('Source Directory:', str(sys.argv[1]))
print ('Destination Directory:', str(sys.argv[2]))

for i in os.listdir(sys.argv[1]):
    fullSource = (os.path.join(sys.argv[1], i))
    fullDestination = (os.path.join(sys.argv[2], i))
    newfile = open(fullDestination, "x")
    for line in fileinput.input(fullSource, mode='rb'):  # explicite binary mode
        line = line.decode('latin1')   # convert to string in Python3
        matchObj = re.search('(?<!\r)\n', line)
        if matchObj:
            newfile.write(line.rstrip('\r\n'))
        else:
            newfile.write(line)
    newfile.close
    print ("created " + fullDestination)

您的正则表达式正确匹配的\n字符前面没有\r

>>> re.search('(?<!\r)\n', 'abc\r')
>>> re.search('(?<!\r)\n', 'abc\r\n')
>>> re.search('(?<!\r)\n', 'abc\n')
<_sre.SRE_Match object; span=(3, 4), match='\n'>

你的ifwrite错了:

if matchObj:  # "If line ends with '\n'"
    # Won't strip anything, because line ends with '\n', not '\r\n'.
    newfile.write(line.rstrip('\r\n'))
else:
    newfile.write(line)

你可能想这样做:

if not matchObj:  # "If line ends with '\r\n'"
    # Note that strip('\r\n') removes these two characters, but does not add '\n' back.
    newfile.write(line.replace('\r\n', '\n'))
else:
    newfile.write(line)

顺便说一句,你不需要正则表达式来做你想做的事情,endswith()应该足够了:

if line.endswith('\r\n'):
    newfile.write(line.replace('\r\n', '\n'))
else:
    newfile.write(line)

实际上,replace()本身就足够了:

newfile.write(line.replace('\r\n', '\n'))

相关问题 更多 >