python即时标记看不懂怎么办,Python项目之即时标记

本文介绍了如何使用Python通过正则表达式和自定义处理程序,将文本文件转换为HTML格式,实现了标题、强调、URL和邮件的自动标记。通过`Parser`、`Rule`和`Handler`类,展示了如何运用编程技巧简化HTML转换过程。
摘要由CSDN通过智能技术生成

这个项目是《Python基础教程》后面的项目之一。当从一个不想写HTML代码的人那里得到一个文本文件,希望把它转成HTML的格式来当作一个网页来使用。人工添加标签是繁琐的,因此想写一个程序来自动完成。这类问题称之为即时标记。

主要是应用Python出色的文本处理能力——使用正则表达式将纯文本文件改写成语言(如HTML)中的标记,要做的工作基本上是将各种文本元素分类,比如标题和被强调的文本,然后明确地标记它们。

使用的方法:

1.对文件进行读写,从标准注入读取(sys.stdin),利用print输出等。

2.对所输入的行进行迭代。

3.使用了一些字符串方法。

4.re模块

程序分为四个模块:语法分析器、规则、过滤器以及处理程序。

语法分析器:读取文本,管理其他类。

规则:为每个种类的块定制规则,检测适用的块类型并且进行适当的格式化。

过滤器:包装一些处理内嵌元素的正则表达式。

self.addFilter(r'\*(.+?)\*', 'emphasis')

self.addFilter(r'(http://[\.a-z0-9A-Z/]+)', 'url')

self.addFilter(r'([\.a-zA-Z]+@[\.a-zA-Z]+[a-zA-Z]+)','mail')

这三个过滤器分别是关于强调的内容,关于URL,关于email。

处理程序:产生不同种类的标记。

具体实现代码:

处理程序(handles.py):

class Handler:

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: match.group(0)

return result

return substitution

class HTMLRenderer(Handler):

def start_document(self):

print '

...'

def end_document(self):

print ''

def start_paragraph(self):

print '

'

def end_paragraph(self):

print '

'

def start_heading(self):

print '

'

def end_heading(self):

print ''

def start_list(self):

print '

  • '

def end_list(self):

print '

'

def start_listitem(self):

print '

'

def end_listitem(self):

print '

'

def start_title(self):

print '

'

def end_title(self):

print ''

def sub_emphasis(self, match):

return '%s' %match.group(1)

def sub_url(self, match):

return '%s' % (match.group(1), match.group(1))

def sub_mail(self, match):

return '%s' % (match.group(1), match.group(1))

def feed(self, data):

print data

规则(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):

"""

"""

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

主程序(markup.py):

import sys, re

from handlers import *

from util import *

from rules import *

class Parser:

def __init__(self, handler):

self.handler = handler

self.rules = []

self.filters = []

def addRule(self, rule):

self.rules.append(rule)

def addFilter(self, pattern, name):

def filter(block, handler):

return re.sub(pattern, 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, handler):

Parser.__init__(self, handler)

self.addRule(ListRule())

self.addRule(ListItemRule())

self.addRule(TitleRule())

self.addRule(HeadingRule())

self.addRule(ParagraphRule())

self.addFilter(r'\*(.+?)\*', 'emphasis')

self.addFilter(r'(http://[\.a-zA-Z/]+)', 'url')

self.addFilter(r'([\.a-zA-Z]+@[\.a-zA-Z]+)', 'mail')

handler = HTMLRenderer()

parser = BasicTextParser(handler)

parser.parse(sys.stdin)

补充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 = []

运行结果:

被处理的文本:

处理后的结果为:

6720de323fb408413669b4273eadc120.png

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值