#py2.7 #coding:utf-8 import re import os import chardet def filter_tag(htmlstr): re_cdata = re.compile('<!DOCTYPE HTML PUBLIC[^>]*>', re.I) re_script = re.compile('<s*script[^>]*>[^<]*<s*/s*scripts*>', re.I) #过滤脚本 re_style = re.compile('<s*style[^>]*>[^<]*<s*/s*styles*>', re.I) #过滤style re_br = re.compile('<brs*?/?>') re_h = re.compile('</?w+[^>]*>') re_comment = re.compile('<!--[sS]*-->') s = re_cdata.sub('', htmlstr) s = re_script.sub('', s) s=re_style.sub('',s) s=re_br.sub(' ',s) s=re_h.sub(' ',s) s=re_comment.sub('',s) blank_line=re.compile(' +') s=blank_line.sub(' ',s) s=re.sub('s+',' ',s) s=replaceCharEntity(s) return s def replaceCharEntity(htmlstr): CHAR_ENTITIES={'nbsp':'','160':'', 'lt':'<','60':'<', 'gt':'>','62':'>', 'amp':'&','38':'&', 'quot':'"','34':'"'} re_charEntity=re.compile(r'&#?(?P<name>w+);') #命名组,把 匹配字段中w+的部分命名为name,可以用group函数获取 sz=re_charEntity.search(htmlstr) while sz: #entity=sz.group() key=sz.group('name') #命名组的获取 try: htmlstr=re_charEntity.sub(CHAR_ENTITIES[key],htmlstr,1) #1表示替换第一个匹配 sz=re_charEntity.search(htmlstr) except KeyError: htmlstr=re_charEntity.sub('',htmlstr,1) sz=re_charEntity.search(htmlstr) return htmlstr if __name__=='__main__': cpath=os.getcwd() for root,dirs,files in os.walk(cpath): for file in files: if file.endswith('htm') or file.endswith('html'): f=open(root+os.path.sep+file) stream=f.read() htmlstr =stream.decode(chardet.detect(stream)['encoding']) rs=filter_tag(htmlstr) f.close() txtname=re.sub(r'.htm*$','.txt',file) print txtname f=open(root+os.path.sep+txtname,'w') f.write(rs.encode('utf-8')) f.close()
总结:
转义符:
. 匹配除换行符以外的任意字符
w 匹配字母或数字或下划线或汉字
s 匹配任意的空白符
d 匹配数字
匹配单词的开始或结束
^ 匹配字符串的开始
$ 匹配字符串的结束
W 匹配任意不是字母,数字,下划线,汉字的字符
S 匹配任意不是空白符的字符
D 匹配任意非数字的字符
B 匹配不是单词开头或结束的位置
[^x] 匹配除了x以外的任意字符
[^aeiou] 匹配除了aeiou这几个字母以外的任意字符
常用的限定符代码/语法说明:
*重复零次或更多次
+重复一次或更多次
?重复零次或一次
{n}重复n次
{n,}重复n次或更多次
{n,m}重复n到m次
关于命名组:
命名组:(?P<name>.....),详见:http://scm002.iteye.com/blog/1491521
这篇文章里面还提到了界定( 问号开头,前向则有个'<'号,非则有个'!' 号 ):
前向界定 (?<=…)
后向界定 (?=…)
前向非界定 (?<!....)
后向非界定 (?!.....)