Python多个正则表达式替换

时间:2012-01-22 14:27:20

标签: python regex replace

我是一个蟒蛇新手。 我一直在寻找,但发现我的观念只有一点点。 Windows上的Python 2.7(我选择了python,因为它是多平台,结果可以在Windows上移植)。

我想制作一个脚本,在文件夹中搜索* .txt UTF-8文本文件,加载内容(一个文件在一个之后),将非ascii字符更改为html权限,然后添加html标签在每行的开头和结尾处,但是标签的两个变体,一个用于文件的头部,一个用于文件的尾部,其中(头尾)由空行分隔。之后,所有结果必须写入另一个文本文件,如* .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

它起作用,效果很好,但是对于这个任务,fileinput不是我认为的可行方式。

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

结果相同。请帮忙。

编辑:我刚用hexeditor检查了结果文件,并且在每个结束标记之前有一个x0D字节!为什么呢?

Edit2:更改为更符合逻辑的方法

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

Edit3:使用hexeditor我看到了混乱结果的原因:每个CRLF之前的额外CR(x0D)字节。 我追踪了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 个答案:

答案 0 :(得分:3)

这里根本不需要正则表达式,只需这样做:

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 :(得分:1)

#!/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))

Example

$ python txt2html.py c:\root\dir