从字符串中提取模板(模式)并使用此模式解析其他字符串。
项目描述
简介
给定一些字符串(或文件),这个库可以从它们之间提取一个共同模板(方法 learn)——有些人称之为“反向模板”。创建模板后,您可以使用它来解析其他字符串/文件——parse 方法将返回文件中更改的部分(“空位”)。它做的事情与模板库(如 Jinja)相反。但目前,它只能识别固定变量(例如,它不能创建 for 和 if 块)。
如果您有模板和“空位”,也可以使用 join 方法填充“空位”——它将返回一个填充了模板的字符串。还有一些其他功能
如果您不希望/需要使用 Templater(主类)为您创建模板,您可以将预处理的模板(手动创建或在使用 learn 创建并保存到某处的模板)传递给它。
可以将学习和解析过程分开,因为学习过程通常只执行一次,与解析过程相比,它需要更多的时间。为了使这个过程更加方便,Templater 提供了 dump、save、load 和 open 等方法,因此您可以学习并保存模板定义,以便以后加载和解析,您想解析多少次都可以(也可以加载、学习更多并保存)。
templater 使用简单,易于学习,并能为您做大量工作(例如:学习算法的部分是用 C 实现的,以提高性能)。您有 5 分钟时间吗?那么就通过 示例 来学习吧。
安装
Templater 在 PyPI 上可用,因此安装它就像执行以下命令一样简单:
pip install templater
或者您也可以下载最新版本,并使用 setup.py 进行安装
git clone https://turicas@github.com/turicas/templater.git cd templater python setup.py build install
术语
以下是一些定义/概念,我们应该明确说明
模板:整个对象(Templater 的实例)。
文档:具有某种模式的字符串或文件。您将使用文档使模板对象学习并识别这些模式,这样以后您就可以使用模板对象来解析文档,并仅获取不是“静态”的信息。
块:模板的固定部分。在运行 learn 时可以更改(数量和大小)。
空白:也称为孔或变量,空白是模板中在具有相同模板的文档之间发生变化的部分。
模板定义:存储在模板中定义模板的信息(它是一个具有非常简单语法的 Python 列表,描述了模板是如何组成的)。
标记:当您想要保存模板时,应该在块之间放置某些内容来“标记”空白(这样以后就可以重建模板定义)。
命名标记:一个标记加上一个标题称为命名标记。它们很方便,也更易于阅读,因为您可以通过名称而不是索引来访问“空白”。
有疑问吗?不用担心,查看 示例,您就会明白。
示例
您需要了解的所有内容都在下面(以及在 examples 目录中)
>>> from templater import Templater >>> documents_to_learn = ['<b> spam and eggs </b>', '<b> ham and spam </b>', '<b> white and black </b>'] # list of documents >>> template = Templater() >>> for document in documents_to_learn: ... template.learn(document) ... >>> print 'Template created:', template._template # template definition Template created: [None, '<b> ', None, ' and ', None, ' </b>', None] >>> document_to_parse = '<b> yellow and blue </b>' >>> print 'Parsing other document:', template.parse(document_to_parse) Parsing other document: ['', 'yellow', 'blue', ''] >>> print 'Filling the blanks:', template.join(['', 'red', 'orange', '']) Filling the blanks: <b> red and orange </b>
您可以将预处理的模板作为列表传递(空白是 None,块是字符串)
>>> t2 = Templater(template=[None, 'Music: ', None, ', Band: ', None]) >>> print t2.join(['', 'Welcome to the Jungle', 'Guns and Roses']) Music: Welcome to the Jungle, Band: Guns and Roses
…或者您可以将带有标记的字符串传递,然后 Templater 将为您创建列表
>>> t3 = Templater(template='language=#,cool=#', marker='#') >>> print t3.join(['', 'Python', 'YES', '']) language=Python,cool=YES
保存和打开模板非常简单
>>> template.save('my-first-template.html', marker='|||') >>> # and some time later... >>> loaded_template = Templater.open('my-first-template.html', marker='|||') >>> print loaded_template.parse('<b> Romeo and Juliet </b>') ['', 'Romeo', 'Juliet', '']
save 和 dump 之间的区别在于,save 存储模板字符串,用标记填充空白,而 dump 使用 cPickle 保存整个 Templater 对象。对是
save 和 open(带有标记的原始模板字符串)
load 和 dump(整个对象)
注意:save 总是在文件末尾添加一个 \n;load 删除文件末尾的尾随 \r\n 或 \n(如果有的话)。
注意-2:在传递预处理的模板(使用 Templater 初始化器或 Templater.open)时,请确保它以标记 开始和结束。
如果您遇到了很多空白,可以配置学习过程:只需调整 min_block_size - 这是模板中创建新块的最低字符数
>>> str_1 = 'my favorite color is blue' >>> str_2 = 'my favorite color is violet' >>> t = Templater() # default min_block_size = 1 >>> t.learn(str_1) >>> t.learn(str_2) >>> print t._template [None, 'my favorite color is ', None, 'l', None, 'e', None]
我们不希望那里有'l'和'e',对吧?所以
>>> t = Templater(min_block_size=2) >>> t.learn(str_1) >>> t.learn(str_2) >>> print t._template [None, 'my favorite color is ', None]
您还可以向模板中添加“标题” - 标题将是您标记的名称,因此您将拥有一个带有命名标记的模板,而parse将返回一个dict而不是list。这比使用列表索引更易于阅读,让我们看看
>>> import re >>> # Let's create a regexp that cases with '{{var}}' (it'll be our marker) >>> regexp_marker = re.compile(r'{{([a-zA-Z0-9_-]*)}}') >>> template = Templater('{{first-var}}<b>{{second-var}}</b>{{third-var}}', marker=regexp_marker) >>> # The template knows the name of each marker just using the regexp provided >>> # Passing marker as regexp to specify named markers also work for Templater.open >>> print template.parse('This <b> is </b> a test.') {'second-var': ' is ', 'third-var': ' a test.', 'first-var': 'This '} >>> # To save the template with named markers we need to provide a Python string. >>> # Templater will call .format() of this string for each marker with its name >>> template.save('template-with-named-markers.html', marker='--{}--') >>> # Will save '--first-var--<b>--second-var--</b>--third-var--\n'
如果您有一个没有标题的模板,只需使用add_headers方法向其中添加即可
>>> t = Templater('+<tr><td>+</td><td>+</td></tr>+', marker='+') >>> t.parse('<tr><td>hello</td><td>world</td></tr>') ['', 'hello', 'world', ''] >>> t.add_headers(['before', 'first-column', 'second-column', 'after']) >>> t.parse('<tr><td>hello</td><td>world</td></tr>') {'after': '', 'before': '', 'first-column': 'hello', 'second-column': 'world'}
注意:命名标记有一个问题:如果您使用它们,则无法运行learn
备注
我真的很想知道您是否在使用此项目,以及您对它的看法。如果您有新功能的想法、发现错误或只想说“谢谢,我在使用它!”,请通过alvarojusten at gmail联系我。
如果您想编写一些代码,只需在GitHub上fork它并创建一个pull request。以下是一些技术说明
此项目使用测试驱动开发。
测试使用Python 2.7.2在Ubuntu 11.10 amd64上运行。
您可以在CHANGELOG.rst中查看版本之间的更改。
此项目使用语义版本(感谢Tom Preston-Werner)。