当前位置: 首页 > news >正文

python即时标记

将纯文本文件改写成标记语言格式的文件(如Html语言)

python版本3.6.2

准备文档test_input.txt

Welcome to World Wide Spam. Inc.



These are the corporate web pages of *World Wide Spam*,Inc.We hope
you find your stay enjoyable,and that you will sample many of our
products.

A short history if the company

World Wide Spam was started in the summer of 2000.The business
concept was to ride the dot-com wave ande to make money both through
bulk email and by selling canned meat online.

After receiving several complaints from customers who weren't
satisfied by their bulk email.World Wide Spam altered their profile,
and focused 100%on canned goods.Today,they rank as the world's
13,892nd online supplier of SPAM.

Destinations

From this page you may visit several of our intersting web pages:

-What is SPAM?(http://wwspam.fu/whatisspam)

-How do they make it?(http://wwspam.fu/howtomakeit)

-Why should I eat it?(http://wwspam.fu/whyeatif)

How to get in touch with us

You can get in touch with us in *many* ways: By phone (555-1234),by
email (wwspam@wwspam.fu) or by visiting our customer feedback page
(http://wwspam.fu/feedback).

 

初次实现,找出文本块

    找出块的一个简单的方法就是收集行,直到遇到一个空行,就返回之前收集的行,这些返回的行就是一个块,然后接着收集,不要收集空行也不需要放回空块

文本块生成器util.py

#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=[]
            

lines生成器只是在文件的最后一行追加一个空行,blocks生成器基本完成了块的收集

向收集到代表块的字符串添加标记(例如:页面开始标记,段落标记)

simple_markuo.py

#! /usr/bin/env python
#coding=utf-8
#simple_markup.py

import sys, re
from util import *

print('<html><head><title>...</title><body>')

title=True
for block in blocks(sys.stdin):
    block=re.sub(r'\*(.+?)\*',r'<em>\1</em>',block)
    if title:
        print('<h1>')
        print(block)
        print('</h1>')
        title=False
    else:
        print('<p>')
        print(block)
        print('</p>')
print('</body></html>')

我是在windows下运行的  在控制台执行

python mark.py <test_input.txt> test_input.html

接下来进一步实现更具体的功能,对其进行扩展。

handlers.py

#! /usr/bin/env python
#coding=utf-8
#handler.py

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(0)
            return result
        return substitution
    
class HTMLRenderer(Handler):
    """
    用于生成HTML的具体处理程序
    
    HTMLRenderer内的方法都可以通过超类处理程序的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_heading(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)

 

rules.py

#! /usr/bin/env python
#coding=utf-8
#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(slef,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
    

 

mark.py

#! /usr/bin/env python
#coding=utf-8
#mark.py
#控制台执行命令   python mark.py <test_input.txt> test_input.html

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]+[a-zA-Z]+)','mail')
        
handler=HTMLRenderer()
parser=BasicTextParser(handler)
parser.parse(sys.stdin)
        

 

这里只是简单的添加了一下标签,具体的可以根据自己需求对代码进行改动。

最终效果图

最后提醒,写代码时不要着急,不然敲错了一个字母就会影响整体的运行

其中遇到了一个错误在这里粘一下:

这个是正则表达式一个字符写错了导致的。

欢迎批评指正。

 

转载于:https://www.cnblogs.com/soul-mate/p/7462390.html

相关文章:

  • try catch 小结 , node的回调callback里不能捕获异常 , 不能被v8优化(现在能了),...
  • 实现多线程的另一种方式-Callable
  • BeginInvoke异步线程
  • ASP.NET Core 运行原理解剖[3]:Middleware-请求管道的构成
  • UVA - 10763 Foreign Exchange
  • 网络编程概述和三要素(IP/端口号/协议)以及Socket通信原理
  • 张春晖让视频的每词每句都可搜索:Autotiming 可以自动配字幕,还将改变哪些领域?...
  • 寄存器调试 (1):应用层基于shell命令访问
  • 谱聚类实例
  • postgresql update returning
  • 其实吧,360的开发,素质也没高到哪去,看代码就看出来了
  • 判断js数据类型
  • Linux上给不是管理员的用户增加安装软件的权限
  • 【已解决】项目加载失败,Web应用程序项目XX已配置为使用IIS
  • JDBC连接数据库:单线程、多线程、批处理插入数据的对比
  • 〔开发系列〕一次关于小程序开发的深度总结
  • Android 控件背景颜色处理
  • Docker 笔记(2):Dockerfile
  • exports和module.exports
  • JWT究竟是什么呢?
  • Mithril.js 入门介绍
  • Objective-C 中关联引用的概念
  • orm2 中文文档 3.1 模型属性
  • 阿里云ubuntu14.04 Nginx反向代理Nodejs
  • 对象引论
  • 优化 Vue 项目编译文件大小
  • 如何用纯 CSS 创作一个菱形 loader 动画
  • 如何在 Intellij IDEA 更高效地将应用部署到容器服务 Kubernetes ...
  • 新海诚画集[秒速5センチメートル:樱花抄·春]
  • #stm32驱动外设模块总结w5500模块
  • #我与Java虚拟机的故事#连载15:完整阅读的第一本技术书籍
  • $.ajax()方法详解
  • $.type 怎么精确判断对象类型的 --(源码学习2)
  • (1)(1.8) MSP(MultiWii 串行协议)(4.1 版)
  • (C++17) std算法之执行策略 execution
  • (Repost) Getting Genode with TrustZone on the i.MX
  • (附源码)springboot 个人网页的网站 毕业设计031623
  • (学习日记)2024.03.25:UCOSIII第二十二节:系统启动流程详解
  • (一)搭建springboot+vue前后端分离项目--前端vue搭建
  • ******IT公司面试题汇总+优秀技术博客汇总
  • ***php进行支付宝开发中return_url和notify_url的区别分析
  • ./configure、make、make install 命令
  • .MyFile@waifu.club.wis.mkp勒索病毒数据怎么处理|数据解密恢复
  • .Net IE10 _doPostBack 未定义
  • .net 验证控件和javaScript的冲突问题
  • .NET 自定义中间件 判断是否存在 AllowAnonymousAttribute 特性 来判断是否需要身份验证
  • .Net+SQL Server企业应用性能优化笔记4——精确查找瓶颈
  • .Net下使用 Geb.Video.FFMPEG 操作视频文件
  • .net之微信企业号开发(一) 所使用的环境与工具以及准备工作
  • @GlobalLock注解作用与原理解析
  • [ 攻防演练演示篇 ] 利用通达OA 文件上传漏洞上传webshell获取主机权限
  • [ajaxupload] - 上传文件同时附件参数值
  • [Angular] 笔记 21:@ViewChild
  • [C++]类和对象【下】
  • [CareerCup] 13.1 Print Last K Lines 打印最后K行