动手写的Python的HTML语法分析器(面向对象)
生活随笔
收集整理的這篇文章主要介紹了
动手写的Python的HTML语法分析器(面向对象)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
動手寫的Python的HTML語法分析器(面向對象)
# -*- coding: cp936 -*-
class Handler:
"""
處理從parser調用的方法對象
這個解析器會在每個塊的開始部分調用start()和end()方法,使用合適的塊名作為參數。sub()會用于
正則表達式替換中,當使用了'emphasis'這樣的名字調用時,它會返回核實的替換函數
"""
def callback(self,prefix,name , *args):
method = getattr(self , prefix + name , None)
if callable(method):return method(*args)
def start(self ,name):
self.callback('start_',name)
def end(self,name):
self.callback('end_' ,name)
def sub(self,name):
def substitution(match):
result = self.callback('sub_', name,match)
if result is None:
result = match.group(1)
return result
return substitution
class HTMLRenderer(Handler):
"""
用于生成HTML的具體處理程序
類中所有的方法都可以通過超類處理程序的START()、end()、sub()方法來訪問,他們實現了HTML的基本標簽
"""
def start_document(self):
print '<html><head><title>...</title></head><body>'
def end_document(self):
print '</body></html>'
def start_paragraph(self):
print '<p>'
def end_paragraph(self):
print '</p>'
def start_heading(self):
print '<h2>'
def end_heading(self):
print '<h2>'
def start_list(self):
print '<ul>'
def end_list(self):
print '</ul>'
def start_listitem(self):
print '<li>'
def end_listitem(self):
print '</li>'
def start_title(self):
print '<h1>'
def end_title(self):
print '</h1>'
def sub_emphasis(self,match):
return '<em>%s<em>' % match.group(1)
def sub_url(self ,match):
return '<a href="%s">%s</a>' % (match.group(1),match.group(1))
def sub_mail(self,match):
return '<a href="mailto:%s">%s</a>' % (match.group(1),match.group(1))
def feed(self,data):
print data
# -*- coding: cp936 -*-
#rules.py
class Rule:
"""所有規則的基類"""
def action(self,block ,handler):
handler.start(self.type)
handler.feed(block)
handler.end(self.type)
return True
class HeadingRule(Rule):
"""
標題占一行,且標題的數目不大于70個字符,且最后不能以冒號結尾
"""
type = 'heading'
def condition(self,block):
return not '\n' in block and len(block)<=70 and not block[-1]==':'
class TitleRule(HeadingRule):
"""
題目是文檔的第一個塊,前提他是大標題
"""
type = 'title'
first= True
def condition(self,block):
if not self.first:return False
self.first = False
return HeadingRule.condition(self, block)
class ListItemRule(Rule):
type ='listitem'
def condition(self,block):
return block[0]=='-'
def action(self,block,handler):
handler.start(self.type)
handler.feed(block[1:].strip())
handler.end(self.type)
return True
class ListRule(ListItemRule):
type = 'list'
inside = False
def condition(self,block):
return True
def action(self,block,handler):
if not self.inside and ListItemRule.condition(self, block):
handler.start(self.type)
self.inside=True
elif self.inside and not ListItemRule.condition(self, block):
handler.end(self.type)
self.inside=False
return False
class ParagraphRule(Rule):
type ='paragraph'
def condition(self,block):
return True
#util.py
def lines(file):
for line in file:yield line
yield '\n'
def blocks(file):
block =[]
for line in lines(file):
if line.strip():
block.append(line)
elif block:
yield ''.join(block).strip()
block=[]
import sys , re
from handlers import *
from util import *
from rules import *
class Parser:
"""
the processer of this , read data ,then use rule , and control to process data block
"""
#initial
def __init__(self,handler):
self.handler = handler
self.rules =[]
self.filters =[]
#addrule to the Parser
def addRule(self,rule):
self.rules.append(rule)
#add filter to the Parser
def addFilters(self,patten,name):
def filter(block , handler):
return re.sub(patten,handler.sub(name),block)
self.filters.append(filter)
def parse(self,file):
self.handler.start('document')
for block in blocks(file):
for filter in self.filters:
block = filter(block , self.handler)
for rule in self.rules:
if rule.condition(block):
last = rule.action(block,self.handler)
if last:break
self.handler.end('document')
class BasicTextParser(Parser):
def __init__(self,hanler):
Parser.__init__(self,handler)
self.addRule(ListRule())
self.addRule(ListItemRule())
self.addRule(TitleRule())
self.addRule(HeadingRule())
self.addRule(ParagraphRule())
self.addFilters(r'\*(.+?)\*', 'emphasis')
self.addFilters(r'(http://[\.a-zA-z/]+)', 'url')
self.addFilters(r'([\.a-zA-Z/]+@[\.a-zA-z]+[a-zA-Z]+)', 'mail')
handler = HTMLRenderer()
parser = BasicTextParser(handler)
f= open(r'D://python27/input.txt')
parser.parse(f)
主要包括4個文件,util.py文件主要負責截取每個塊。
rules.py文件定義兩個類,超類Rule和分別對應的子類,子類定義了不同的劃分塊的要求,子類包換action函數,調用handler處理
handlers.py定義了處理類,超類定義了方法,子類通過名字調用
markup.py定義了超類parser,定義了子類basicTextParser,超類主要負責創造過濾器,添加規則,對每個塊執行處理。
#handler.py# -*- coding: cp936 -*-
class Handler:
"""
處理從parser調用的方法對象
這個解析器會在每個塊的開始部分調用start()和end()方法,使用合適的塊名作為參數。sub()會用于
正則表達式替換中,當使用了'emphasis'這樣的名字調用時,它會返回核實的替換函數
"""
def callback(self,prefix,name , *args):
method = getattr(self , prefix + name , None)
if callable(method):return method(*args)
def start(self ,name):
self.callback('start_',name)
def end(self,name):
self.callback('end_' ,name)
def sub(self,name):
def substitution(match):
result = self.callback('sub_', name,match)
if result is None:
result = match.group(1)
return result
return substitution
class HTMLRenderer(Handler):
"""
用于生成HTML的具體處理程序
類中所有的方法都可以通過超類處理程序的START()、end()、sub()方法來訪問,他們實現了HTML的基本標簽
"""
def start_document(self):
print '<html><head><title>...</title></head><body>'
def end_document(self):
print '</body></html>'
def start_paragraph(self):
print '<p>'
def end_paragraph(self):
print '</p>'
def start_heading(self):
print '<h2>'
def end_heading(self):
print '<h2>'
def start_list(self):
print '<ul>'
def end_list(self):
print '</ul>'
def start_listitem(self):
print '<li>'
def end_listitem(self):
print '</li>'
def start_title(self):
print '<h1>'
def end_title(self):
print '</h1>'
def sub_emphasis(self,match):
return '<em>%s<em>' % match.group(1)
def sub_url(self ,match):
return '<a href="%s">%s</a>' % (match.group(1),match.group(1))
def sub_mail(self,match):
return '<a href="mailto:%s">%s</a>' % (match.group(1),match.group(1))
def feed(self,data):
print data
# -*- coding: cp936 -*-
#rules.py
class Rule:
"""所有規則的基類"""
def action(self,block ,handler):
handler.start(self.type)
handler.feed(block)
handler.end(self.type)
return True
class HeadingRule(Rule):
"""
標題占一行,且標題的數目不大于70個字符,且最后不能以冒號結尾
"""
type = 'heading'
def condition(self,block):
return not '\n' in block and len(block)<=70 and not block[-1]==':'
class TitleRule(HeadingRule):
"""
題目是文檔的第一個塊,前提他是大標題
"""
type = 'title'
first= True
def condition(self,block):
if not self.first:return False
self.first = False
return HeadingRule.condition(self, block)
class ListItemRule(Rule):
type ='listitem'
def condition(self,block):
return block[0]=='-'
def action(self,block,handler):
handler.start(self.type)
handler.feed(block[1:].strip())
handler.end(self.type)
return True
class ListRule(ListItemRule):
type = 'list'
inside = False
def condition(self,block):
return True
def action(self,block,handler):
if not self.inside and ListItemRule.condition(self, block):
handler.start(self.type)
self.inside=True
elif self.inside and not ListItemRule.condition(self, block):
handler.end(self.type)
self.inside=False
return False
class ParagraphRule(Rule):
type ='paragraph'
def condition(self,block):
return True
#util.py
def lines(file):
for line in file:yield line
yield '\n'
def blocks(file):
block =[]
for line in lines(file):
if line.strip():
block.append(line)
elif block:
yield ''.join(block).strip()
block=[]
?
#markup.pyimport sys , re
from handlers import *
from util import *
from rules import *
class Parser:
"""
the processer of this , read data ,then use rule , and control to process data block
"""
#initial
def __init__(self,handler):
self.handler = handler
self.rules =[]
self.filters =[]
#addrule to the Parser
def addRule(self,rule):
self.rules.append(rule)
#add filter to the Parser
def addFilters(self,patten,name):
def filter(block , handler):
return re.sub(patten,handler.sub(name),block)
self.filters.append(filter)
def parse(self,file):
self.handler.start('document')
for block in blocks(file):
for filter in self.filters:
block = filter(block , self.handler)
for rule in self.rules:
if rule.condition(block):
last = rule.action(block,self.handler)
if last:break
self.handler.end('document')
class BasicTextParser(Parser):
def __init__(self,hanler):
Parser.__init__(self,handler)
self.addRule(ListRule())
self.addRule(ListItemRule())
self.addRule(TitleRule())
self.addRule(HeadingRule())
self.addRule(ParagraphRule())
self.addFilters(r'\*(.+?)\*', 'emphasis')
self.addFilters(r'(http://[\.a-zA-z/]+)', 'url')
self.addFilters(r'([\.a-zA-Z/]+@[\.a-zA-z]+[a-zA-Z]+)', 'mail')
handler = HTMLRenderer()
parser = BasicTextParser(handler)
f= open(r'D://python27/input.txt')
parser.parse(f)
轉載于:https://www.cnblogs.com/lzhenf/archive/2012/03/06/2382056.html
總結
以上是生活随笔為你收集整理的动手写的Python的HTML语法分析器(面向对象)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java中getResource()的用
- 下一篇: 2017年html5行业报告,云适配发布