2016-11-24 1 views
0

Я пытаюсь использовать re в Python 3, чтобы разделить мои структурированные текстовые файлы на несколько. это структура текстового файлаКак разбить структурированные текстовые файлы в нескольких текстовых файлах в python 3

Debates 

Content 

======================= #there is a space in the front of this line 

Debates 

Content 

======================= #there is a space in the front of this line 

Я хотел бы получить что-то вроде

1.txt 
Debates 
Content 
======================= 

2.txt 
Debates 
Content 
======================= 

и так далее

Это код, который я пытаюсь использовать

import re 

data=open("file.txt", encoding="utf-8") 
data=data.read() 

found = re.findall(r'\n*(Debates.*\s\n\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=\=)\n*', data, re.M | re.S) 
[open(str(i)+'.txt', 'w').write(found[i-1]) for i in range(1, len(found)+1)] 

Python не дает мне какой-либо ошибки, но, кажется, замерзает, когда я пытаюсь. Кто-нибудь знает, как это сделать? Спасибо заранее!

+0

'\ = \ = \ = \ = \ = \ = \ = \ = \ = \ = \ = \ = \ = \ = \ = \ = \ = \ = \ = \ = \ = \ = \ = ': действительно? –

+0

спасибо, что позволил мне понять, что я совершил ошибку! Тем не менее, в настоящее время менее месяца я использую Python и фактически изучаю все, что связано с программированием ... Поэтому мой ответ на вас - это ДА! :) – Bene

+0

Это не ошибка, так как это правильно, но когда вы видите что-то брезгливое, это часто признак того, что есть более простой способ. –

ответ

1

Если вы не должны использовать регулярное выражение, то я хотел бы предложить следующее:

with open('file.txt', 'r', encoding="utf-8") as file: 
    data = file.read().split(' =======================\n')[:-1] 
for i, debate in enumerate(data): 
    with open(str(i+1) + '.txt', 'w') as dfile: 
     dfile.write(debate) 
+0

Приятное использование .split() .Я бы закрыл входной файл после его прочтения. –

+1

@RobinKoch Я использую 'with' заявление, поэтому' файл' будет закрыт автоматически. –

+1

Я знаю, но только после того, как будут созданы другие файлы. Я предлагаю выделить цикл for. Нет смысла хранить файл после чтения файла. Кроме того, уровень отступа будет меньше. –

0

Вы можете просто использовать это.

(\bDebates.*?\n\s={23}) 

Просмотреть демонстрационный файл.

https://regex101.com/r/ZQCR62/1

Используйте re.DOTALL и никаких других флагов.

+0

спасибо за подсказку! Тем не менее он продолжает давать мне эту ошибку UnicodeEncodeError: кодек ascii не может кодировать символ '\ xa0' в позиции 34: порядковый номер не в диапазоне (128) – Bene

+0

@Bene den u нужно открыть файл с помощью кодеков и правильной кодировкой – vks

0
  1. В вашем RegExp перед знаками равенства есть символ новой строки, это может быть причина, по которой он не соответствует.
  2. Вам не нужно избегать равных знаков.
  3. Поток равных знаков написан более компактно, как ={23}, который соответствует, ну, равнозначным равным. Вы также можете поместить за ним $, чтобы отметить конец строки: ={23}$
  4. и самое главное: ваши кванторы являются жадными, пытаясь соответствовать как можно больше. Таким образом, ваш первый .* соответствует всем файлам до последней разделительной линии. Если вы хотите иметь несколько совпадений, используйте знак вопроса: .*?, который пытается совместить как можно меньше.
  5. И, как упоминалось ранее, RegEx - это не лучший способ пойти в этой ситуации.

Тем не менее мой рабочий код:

import re 

with open("file.txt", encoding='utf-8') as f: 
    data = f.read() 

found = re.findall(r'(Debates.*?={23})', data, re.M | re.S) 

[open(str(i)+'.txt', 'w').write(found[i-1]) for i in range(1, len(found)+1)] 
+0

Спасибо для этого! Я пробовал это решение, но он продолжает давать мне эту ошибку. UnicodeEncodeError: кодек «ascii» не может кодировать символ «\ xa0» в позиции 34: порядковый номер не в диапазоне (128). Я думаю, что проблема заключается в знаке = ... – Bene

+0

@ Бене, наверное, нет. Проблема находится в позиции 34. В представленном вами примере это находится в середине первой строки равных знаков. Но персонажа '\ xa0' нет. Возможно, вам следует проверить/предоставить исходный файл (или, по крайней мере, первые 40 байтов). –