2016-04-04 3 views
0

Я пытаюсь обнаружить автономные линии в файле с Python. В файле есть отдельные «LF» (т. Е. \ N) и некоторые комбинации «CRLF» (т. Е. \ R \ n), и я стараюсь просто соответствовать автономным.Обнаружение строк с помощью Python

Я думал, что это будет работать:

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) удаляются. Я что-то упустил?

+2

'\ r' =' CR', не 'LF' и' \ n' шаблон соответствует '\ n', которые не предшествуют с' \ г '. См. [Это демо] (https://ideone.com/2nvBVB) - он работает. –

+0

Извинения, я получал мои персонажи перепутаны. Теперь я отредактировал этот вопрос. –

+1

Да, но ваш код работает. Пожалуйста, покажите «большую картинку» (более связанный код). –

ответ

1

Ну, этот результат не удивительно. fileinput модуль открывает файлы в текстовом режиме по умолчанию, поэтому \r\n автоматически изменятся в одном \n. Поэтому регулярное выражение соответствует каждой строке и удаляет все \n - \r уже удалены fileinput.

Таким образом, вы должны явно использовать двоичный открытый режим. К сожалению, если вы используете Python 3.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) 
+0

Awesome, nice one :) Это только что собрало меня там, кроме как при написании файла у меня получилось дополнительное \ r на каждой строке, поэтому я решил написать обратно в файл в двоичном формате (т.е. я сделал «open» (fullDestination, 'xb') ", а затем передал line.encode в .write, и все было хорошо :) –

0

Ваше регулярное выражение правильно соответствие \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'> 

Ваш if и write неправы:

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')) 
+0

Проблема не была там ... –

+0

@SergeBallesta: тогда у меня есть не понял вопрос –