现在的位置: 首页 > 综合 > 正文

python 正则表达式过滤文本中的html标签 源代码解析

2013年11月28日 ⁄ 综合 ⁄ 共 1908字 ⁄ 字号 评论关闭
#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*script\s*>', re.I) #过滤脚本
    re_style = re.compile('<\s*style[^>]*>[^<]*<\s*/\s*style\s*>', re.I) #过滤style
    re_br = re.compile('<br\s*?/?>')
    re_h = re.compile('</?\w+[^>]*>')
    re_comment = re.compile('<!--[\s\S]*-->')
    s = re_cdata.sub('', htmlstr)
    s = re_script.sub('', s)
    s=re_style.sub('',s)
    s=re_br.sub('\n',s)
    s=re_h.sub(' ',s)
    s=re_comment.sub('',s)
    blank_line=re.compile('\n+')
    s=blank_line.sub('\n',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 匹配数字

\b 匹配单词的开始或结束

^ 匹配字符串的开始

$ 匹配字符串的结束

\W 匹配任意不是字母,数字,下划线,汉字的字符

\S 匹配任意不是空白符的字符

\D 匹配任意非数字的字符

\B 匹配不是单词开头或结束的位置

[^x] 匹配除了x以外的任意字符

[^aeiou] 匹配除了aeiou这几个字母以外的任意字符


常用的限定符代码/语法说明:

*重复零次或更多次

+重复一次或更多次

?重复零次或一次

{n}重复n次

{n,}重复n次或更多次

{n,m}重复n到m次


关于命名组:

命名组:(?P<name>.....),详见:http://scm002.iteye.com/blog/1491521

这篇文章里面还提到了界定( 问号开头,前向则有个'<'号,非则有个'!' 号 ):

前向界定 (?<=…)

后向界定 (?=…)  

前向非界定 (?<!....)

后向非界定 (?!.....)





抱歉!评论已关闭.