Множественное регулярное выражение Python заменяет - PullRequest
4 голосов
/ 22 января 2012

Я новичок в питоне.Я искал много дней, но нашел только некоторые кусочки своей концепции.Python 2.7 в Windows (я выбрал python, потому что он мультиплатформенный, и результат может быть переносимым в Windows).

Я хотел бы создать скрипт, который ищет в папке текстовые файлы * .txt UTF-8, загружаетсодержимое (один файл за другим), изменяет символы не-ascii на права html, затем добавляет теги html в начале и в конце каждой строки, но 2 варианта тегов, один для заголовка файла и одиндля хвоста файла, который (head-tail) разделен пустой строкой.После этого все результаты должны быть записаны в другой текстовый файл (ы), например * .htm.Чтобы быть наглядным:

unicode1.txt:

űnícődé text line1
űnícődé text line2
[empty line]
űnícődé text line3
űnícődé text line4

результат должен быть в unicode1.htm:

<p class='aaa'>&#369;n&iacute;c&#337;d&eacute; text line1</p>
<p class='aaa'>&#369;n&iacute;c&#337;d&eacute; text line2</p>
[empty line]
<p class='bbb'>&#369;n&iacute;c&#337;d&eacute; text line3</p>
<p class='bbb'>&#369;n&iacute;c&#337;d&eacute; text line3</p>

Я начал разрабатывать ядро ​​своего решения, но я застрял.См. Версии сценариев (для простоты я выбрал кодирование с помощью xmlcharrefreplace).

V1:

import re, cgi, fileinput
file="_utf8.txt"
text=""
for line in fileinput.input(file, inplace=0):
  line=cgi.escape(line.decode('utf8'),1).encode('ascii', 'xmlcharrefreplace')
  line=re.sub(r"^", "<p>", line, 1)
  text=text+re.sub(r"$", "</p>", line, 1)
print text

Это сработало, хороший результат, но я думаю, что ввод файла не подходит для этой задачи.

V2:

import re, cgi, codecs
file="_utf8.txt"
text=""
f=codecs.open(file, encoding='utf-8')
for line in f:
  line=cgi.escape(line,1).encode('ascii', 'xmlcharrefreplace')
  line=re.sub(r"^", "<p>", line, 1)
  text=text+re.sub(r"$", "</p>", line, 1)
f.close()
print text

Результат испортился, закрывающий тег в начале строки заменяет первую букву и т. Д.

V3 (пробный многострочный флаг):

import re, cgi, codecs
file="_utf8.txt"
text=""
f=codecs.open(file, encoding='utf-8')
for line in f:
  line=cgi.escape(line,1).encode('ascii', 'xmlcharrefreplace')
  line=re.sub(r"^", "<p>", line, 1, flags=re.M)
  text=text+re.sub(r"$", "</p>", line, 1, flags=re.M)
f.close()
print text

Тот же результат.

V4 (пробовал 1 регулярное выражение вместо 2):

import re, cgi, codecs
file="_utf8.txt"
text=""
f=codecs.open(file, encoding='utf-8')
for line in f:
  line=cgi.escape(line,1).encode('ascii', 'xmlcharrefreplace')
  text=text+re.sub(r"^(.*)$", r"<p>\1</p>", line, 1)
f.close()
print text

Тот же результат.Пожалуйста, помогите.

Редактировать: Я только что проверил файл результатов с помощью шестнадцатеричного редактора, и перед каждым закрывающим тегом стоит байт x0D перед *1034*!Почему?

Edit2: изменения для более логичного подхода

text+=re.sub(r"^(.*)$", r"<p>\1</p>", line, 1)

Edit3: с гекседором я видел причину испорченного результата: дополнительный байт CR (x0D) перед каждымCRLF.Я разыскал проблему CR, что сделало это: конкатенация с +

# -*- coding: utf-8 -*-
text=""
f=u"unicode text line1\r\n unicode text line2"
for line in f:
  text+=line
print text

Это приводит к:

unicode text line1\r\r\n unicode text line2

Есть идеи, как это исправить?

Ответы [ 2 ]

3 голосов
/ 22 января 2012

Здесь вообще нет необходимости в регулярных выражениях, просто сделайте это:

with open('utf8.txt') as f:
    class_name = 'aaa'
    for line in f:
        if line == '\n':
            classname = 'bbb'
        else:
            # decode / convert line
            line = '<p class="{0}">{1}</p>\n'.format(class_name, line.rstrip())
        # write line to file

Получаемые результаты не выглядят вызванными регулярными выражениями, так как они кажутся правильными.Скорее всего, проблема в строке, где вы делаете кодирование / преобразование.Напечатайте эту строку без добавления тегов, чтобы увидеть, соответствует ли она ожиданиям.

1 голос
/ 22 января 2012
#!/usr/bin/env python
import cgi
import fileinput
import os
import shutil
import sys

def textfiles(rootdir, extensions=('.txt',)):
    for dirpath, dirs, files in os.walk(rootdir):
        for f in files:
            if f.lower().endswith(extensions):
               yield os.path.join(dirpath, f)

def htmlfiles(files):
    for f in files:
        root, _ = os.path.splitext(f)
        newf = root + '.html'
        shutil.copy2(f, newf)
        yield newf

for line in fileinput.input(htmlfiles(textfiles(sys.argv[1])), inplace=True):
    if fileinput.isfirstline():
       klass = 'aaa' # start head part
    line = cgi.escape(line.decode('utf-8').strip())
    line = line.encode('ascii', 'xmlcharrefreplace')
    if not line: # empty line
       klass = 'bbb' # start tail part
       print(line)
    else:
       print('<p class="%s">%s</p>' % (klass, line))

* Пример 1 003 *

$ python txt2html.py c:\root\dir
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...