python练习一—文本转化渲染为html
想学习python已经很久了,以前使用ArcGIS的时候学习过一些简单的python语法,用来进行一些简单的GIS数据处理,但是后来并没有用到工作中也就荒废了,后来断断续续看过一些,最近想学习一门新的语言,就拿python下手了,仔细考(拼)虑(凑)出以下理由(喜欢就是喜欢,不用理由):
- python强大库支持,在科学计算、人工智能等高精尖的领域使用甚广
- 在运维中也算是除shell外的第二语言吧
- 学习渗透测试的时候很多poc都是使用python写的,为了不仅仅停留在使用工具上,进一步学习
- 在web中python也是快速开发的利器
本次学习主要是《python基础教程》第二版,简单回顾了前面几章基础知识后,开始拿后面的练习来学习,虽然代码大部分是直接参考书中源码,但是“纸上得来终觉浅,绝知此事要躬行”可不是废话,学习这件事不动手就是耍流氓,在自己动手编写书中例子的时候对python的语法和思想理解逐渐加深。先来一发
为了避免直接上代码略显突兀,显写出这个练习项目的思路:
先撇开具体实现,想想如果要实现将文本转化位html的做法:
- 文本一定时满足一定规则的
- 读取文本内容
- 根据预定义的规则分析读入的文本内容
- 符合某一种规则的文本加上对应的html标签
- 继续读入文本,回到2继续处理
再回来书中的项目,本项目共包含四个模块
- util.py:负责对文本进行一定的格式化,并读取文本
- rule.py:定义什么样的文本可以转化为什么样的html,两件事儿:
- 定义文本和html对应的规则
- 决定规则对应的处理程序(handler)
- handler.py:将给定规则的文本转换为html
- parse.py:调用util.py读取文本,调用rule.py判断文本对应的规则,调用handler处理给定规则的文本
这样子基本脉络已经清晰了,看代码
util.py
- # -*- coding=utf-8 -*-
- def lines(file):
- '''
- 给每个段落强制添加一个空行
- '''
- for line in file :
- yield line
- yield '\n'
- def blocks(file):
- '''
- 将输入的文件按按空行分块
- '''
- block = []
- for line in lines(file):
- if line.strip():
- # line不是空行,属于一个块
- block.append(line)
- elif block:
- # 当前行是空行,block不为空,块已经结束,返回块
- yield ''.join(block).strip()
- block = []
handler.py
- # -*- coding=utf-8 -*-
- 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 subtitution(match):
- result = self.callback('sub_', name, match)
- if result is None:
- match.group(0)
- return subtitution
- class HTMLRender(Handler):
- def start_document(self):
- print '<html><head><title>...</title></head><body>'
- def end_document(self):
- print '</body>'
- def start_paragraph(self):
- print '<p>'
- def end_paragraph(self):
- print '</p>'
- def start_head(self):
- print '<h2>'
- def end_head(self):
- print '</h2>'
- def start_title(self):
- print '<h1>'
- def end_title(self):
- print '</h1>'
- 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 sub_em(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_email(self, match):
- return '<a href="mailto:%s">%s</a>' % (match.group(1), match.group(1))
- def feed(self, data):
- print data
rule.py
- # -*- coding=utf-8 -*-
- class Rule:
- def action(self, block, handler):
- handler.start(self.type)
- handler.feed(block)
- handler.end(self.type)
- return True
- class HeadRule(Rule):
- '''
- 小标题的规则,没有换行符,长度小于70并且不以:结尾
- '''
- type = 'head'
- def condition(self, block):
- return not '\n' in block and len(block) < 70 and block[-1] != ':'
- class TitleRule(HeadRule):
- '''
- 标题的规则,第一行是就是标题
- '''
- type = 'title'
- first = True
- def condition(self, block):
- if not self.first:
- return False
- self.first = False
- return HeadRule.condition(self, block)
- class ListItemRule(Rule):
- '''
- li的规则,如果block以-开头就是listitem,在显示的时候去除-
- '''
- 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):
- '''
- ul的规则,第一个li开始之前,添加ul,在第一个不是li的时候结束ul
- '''
- 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)
- # 每次返回False,在对block使用完本规则之后继续使用其他规则
- return False
- class ParagraphRule(Rule):
- '''
- p段落规则,当前面所有的规则匹配的时候,默认使用本规则
- '''
- type = 'paragraph'
- def condition(self, block):
- return True
parse.py
- # -*- coding=utf-8
- import re, sys
- from util import *
- from handler import *
- from rule import *
- import ipdb
- class Parser:
- '''
- 解析器,利用rule对文本进行解析并转换为html,利用filter转换块内文本
- '''
- 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):
- #pdb.set_trace()
- self.handler.start('document')
- for block in blocks(file):
- ipdb.set_trace()
- 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):
- '''
- 基本文本解析器,只有h1,h2,p,ul,li,a,em,email
- '''
- def __init__(self, handler):
- Parser.__init__(self, handler)
- self.addRule(ListRule())
- self.addRule(ListItemRule())
- self.addRule(TitleRule())
- self.addRule(HeadRule())
- self.addRule(ParagraphRule())
- self.addFilter(r'\*(.+?)\*', 'em')
- self.addFilter(r'(http://[\.a-zA-Z]+)', 'url')
- self.addFilter(r'([\.a-zA-Z]+@[\.a-zA-Z]+[[a-zA-Z]+)', 'email')
- handler = HTMLRender()
- parser = BasicTextParser(handler)
- parser.parse(sys.stdin)
第一次练习就遇到这个项目显得略大,不过搞清楚思路之后整体把我就没问题了,在练习的过程中还遇到一些问题、学到一些东西,总结如下:
- 子类调用父类的方法(包括__init__)
父类名.方法名(self, 参数)
A类调用B类方法
b = B()
b.方法(参数)
- re模块的sub方法
re.sub(regex_str, replace_str, str)
将str中符合正则表达式regex_str的子串用replace_str代替
如果replace_str是正则表达式,可以使用分组替换,例如
re.sub(r'\*(.+)\*', r'---\1---', "asdasdasd*nskjdfnkjdsnf*sdfsdf")
re.sub(r'\*(.+)\*',lambda m: "---" + m.group(1) + "---" ,"asdasdasd*nskjdfnkjdsnf*sdfsdf")
其实作者里面有两个思想让我触动很深,甚是佩服:
- 一个模块做最少的事,制作自己必须做的事
- 事件的路由分发(借由python发挥的淋漓尽致)
这两种思想让项目整体架构变的很清晰,对扩展也很友好,大写的赞!
这个练习已经写完几天了,今天补上记录一下,代码位置
http://pan.baidu.com/s/1o7JVKKU
python练习一—文本转化渲染为html的更多相关文章
- 15.Python文本转化语音方法
1.用pywin32模块来将文本转化为语音 通过pip install pywin32安装模块,pywin32是个万金油的模块,太多的场景使用到它,但在文本转语音上,它却是个青铜玩家,简单无脑但效果不 ...
- 【NLP】Python NLTK获取文本语料和词汇资源
Python NLTK 获取文本语料和词汇资源 作者:白宁超 2016年11月7日13:15:24 摘要:NLTK是由宾夕法尼亚大学计算机和信息科学使用python语言实现的一种自然语言工具包,其收集 ...
- python Django教程 之模板渲染、循环、条件判断、常用的标签、过滤器
python3.5 manage.py runserver python Django教程 之模板渲染.循环.条件判断.常用的标签.过滤器 一.Django模板渲染模板 1. 创建一个 zqxt_tm ...
- Python数据类型之“文本序列(Text Sequence)”
Python中的文本序列类型 Python中的文本数据由str对象或字符串进行处理. 1.字符串 字符串是Unicode码值的不可变序列.字符串字面量有多种形式: 单引号:'允许嵌入"双&q ...
- Selenium2+python自动化23-富文本(自动发帖)
前言 富文本编辑框是做web自动化最常见的场景,有很多小伙伴遇到了不知道无从下手,本篇以博客园的编辑器为例,解决如何定位富文本,输入文本内容 一.加载配置 1.打开博客园写随笔,首先需要登录,这里为了 ...
- python实现的文本编辑器 - Skycrab - 博客频道 - CSDN.NET
Download Qt, the cross-platform application framework | Qt Project Qt 5.2.1 for Windows 64-bit (VS 2 ...
- 在微信小程序中使用富文本转化插件wxParse
在微信小程序中我们往往需要展示一些丰富的页面内容,包括图片.文本等,基本上要求能够解析常规的HTML最好,由于微信的视图标签和HTML标签不一样,但是也有相对应的关系,因此有人把HTML转换做成了一个 ...
- Python处理json字符串转化为字典
有一个需求,需要用python把json字符串转化为字典 inp_str = " {'k1':123, 'k2': '345','k3','ares'} " import json ...
- Python如何将整数转化成二进制字符串
Python 如何将整数转化成二进制字符串 1.你可以自己写函数采用 %2 的方式来算. >>> binary = lambda n: '' if n==0 else binary( ...
随机推荐
- day 34
1 .内容回顾 #__author : 'liuyang' #date : 2019/4/17 0017 上午 9:01 # 利大于弊,则做之 # 会死于斯,则不去 # 2个 人 晚上 5个题 面试题 ...
- SAS 函数
SAS 函数 SAS函数是编程语言的一个组件,可接受参数.执行计算或进行其他操作并返回值.返回值是字符型或数值型的结果,可用于赋值语句或 表达式中.SAS包含很多函数,也可以自定义函数.在BASE S ...
- 【翻译】Flume 1.8.0 User Guide(用户指南) source
翻译自官网flume1.8用户指南,原文地址:Flume 1.8.0 User Guide 篇幅限制,分为以下5篇: [翻译]Flume 1.8.0 User Guide(用户指南) [翻译]Flum ...
- apt-get update 问题
W: 仓库 “cdrom://Ubuntu 16.04.1 LTS _Xenial Xerus_ - Release amd64 (20160719) xenial Release” 没有 Relea ...
- Visual Studio学习记录
1,一些快捷键记录 1,折叠 ctrl+M+A: 折叠所有代码[官方名:折叠所有大纲提示] ctrl + M + O:折叠全部代码[官方:折叠到定义],但是这个貌似只能折叠代码,xml之类的无效.m+ ...
- How to setup Visual Studio without pain
Visual Studio (VS) can be very hard to install. If you are lucky, one whole day may be enough to ins ...
- Nginx 代理配置
1.反向代理 修改conf\nginx.conf文件, 添加proxy_pass属性 server { listen 7080; #nginx 端口 server_name localhost; #n ...
- oracle远程连接服务器数据库
oracle远程连接数据库,需要配置本地服务,具体步骤如下: 1. 2.添加新的服务 3.输入服务名(例如:orcl3即服务器数据库名) 4.选择TCP协议 5.输入服务器IP(192.268.10. ...
- IntelliJ IDEA 和谐地址及快捷键
转载:http://my.oschina.NET/dyyweb/blog/494504 http://blog.csdn.net/tanlon_0308/article/details/5085473 ...
- display:inline-block; 在css中是什么意思?
inline-block主要的用处是用来处理行内非替换元素的高宽问题的!行内非替换元素,比如span.a等标签,正常情况下士不能设置宽高的,加上该属性之后,就可以触发让这类标签表现得如块级元素一样,可 ...