pyparsing:匹配空行

你好,
我试图使这些东西有效,但我仍然失败.
我有一个由三个要素组成的格式:
\ d {4} m? - \ d(4个数字,可选M,dash,另一个数字)
空的
[空行]( 但没有别的)
虽然``watchname''和``weaveement''是微不足道的,但我无法得到
``Pagebreak''工作正常工作.
#!/usr/bin/env Python
# - * - 编码:UTF-8 - * -
来自pyparsing incort(单词,文字,可选,组,oneormore,tregex,
组合,分校,数字,linestart,lineD,白色,白色,
用...来代替)
parserelement.setDefaultWhitespaceChars('\ t \ r')
WatchSeries = Word(Nums,cract = 4)
watchrev = word(nums,cract = 1)
watchName = combine(WatchSeries +可选('M') +' - ' + WatchRev)
wellement =字面('空')
DEF断裂(S,LOC,令牌):
打印reter(令牌[0])
#return [''for令牌中的令牌[0]]
返回['']
#pagebreak = REGEX('^\ s*$').setParseaction(breaks)
pagebreak = lineStart() + lineend().setParseaction(replacewith
('')
Parser = OneorMore(watchName ^ pagbreak ^ weffempty)
测试= [
" 2134m-2",
"" 3245-3
3456m-5"",
"" 3256-4
4563-4"",
""" 4562m-6
空的
3246-5""
这是给予的
在测试中进行测试:
打印parser.parsestring(测试)
输出应为:
['2134m-2']
['3245-3','3456m-5']
['3256-4','''4563-4']
['4562m-6','<空>','3246-5']
提前致谢!
问候,
Marek

# 回答1


在9月2日,11:38*AM,Marek Kubica
马雷克 -
以下是您程序的一些改进,可以使您更接近
您发布的结果.
1)在重置默认空格字符方面做得很好,因为您
正在进行一些取决于线路的解析
结束.当您执行此操作时,定义末端的表达式很有用
线路以便您可以在明确期望的地方引用它
查找线端:
eol = lineend().suppress()
2)您的第二个测试失败,因为两者之间存在EOL
手表名称.由于您已从默认值集中删除了EOL
空格字符(即,pyparsing将会
自动跳过),然后在阅读后将停止
第一个手表名称.我认为您希望EOL能够解析
否则匹配,因此您可以将其添加到语法定义的末尾:
Parser = OneorMore(watchName ^ pagbreak ^ weftEmpty ^ eol)
现在,这将允许第二次测试通过.
3)您对PageBreak的定义现在看起来还不错,但我不明白
为什么您的测试包含2条空白行只能生成一个
.
pagebreak = linestart() +
lineend().setParseaction(repleastwith(''))
如果您真的只想从测试中获得一个 案例,而不是更改页面上:
pagebreak = oneormore(linestart() +
lineend()).setParseaction(repleastwith(''))
4)WeftEmpty可能需要采取这种解析行动:
weftempty =
文字("空").setParseaction(replacewi th('')
5)(可选)您对解析器的定义使用'^'运算符,
转化为或表达.或表达式评估所有
替代方案,然后选择最长的匹配.你的表情
对他们没有任何歧义,可以评估
使用:
Parser = OneorMore(watchName | pagebrake | weffEmpty | eol)
'|'操作员生成匹配表达式. Matchfirst会做
短路评估 - 匹配的第一个表达式将是
选择作为匹配替代品.
如果您有更多的问题,也可以将它们发布到
pyparsing wiki- Wiki主页上的讨论选项卡已成为一个
运行支持论坛 - 还有一个帮助/讨论邮件
列表.
干杯,
- 保罗
# 回答2


你好,
首先,非常感谢您的出色图书馆,当然还有
还为您广泛而启发性的答案!
好的,我没有考虑这个.但是由于我的程序不仅是解析器,而且是
长期运行的过程和setDefaultWhitespace会修改全局
可变,我对此不太满意.我可以设置空格
在每个元素上,但这肯定是丑陋的.你
接受补丁?我正在考虑某种工厂班级
自动设置白色空间:
这样,就不需要设置可能干扰的怪异价值
与其他Pyparsers一起在同一过程中运行.
正确的.似乎与Whitespace合作需要更好
理解比我有.
不,它应该是一个 同时,我添加了这个.替换确实是一个方便的助手.
好的,调整了它.
您想要这两个中的哪一个?
再次感谢,现在正如我想象的那样,它现在起作用了!
问候,
Marek
# 回答3


在9月3日,4:26 AM,Marek Kubica 我很高兴Pyparsing对您有帮助. Pyparsing正在建立
这些天有自己的动力.我在SVN中有一个新版本,我会放
在下周左右.
Pyparsing并不是真正友好的线程.你肯定
不应使用相同的语法有多个线程.这
我看到人们在多线程应用程序中使用的方法是:1)
同步跨多个线程对单个解析器的访问,2)
创建单线解析器,或使用一组解析器. pyparsing
解析器可以腌制,因此,重新建立解析器的一种快速方法是
在启动时间创建解析器,然后将其腌制到字符串中,然后
根据需要取消新的解析器.
这样,就不需要设置可能干扰的怪异价值
与其他Pyparsers一起在同一过程中运行.
我试图将您的TokenFactory类制作原型,但是一旦我到了
作为实现__getAttribute __返回相应的pyparsing
课堂,我看不到如何抓住该类生成的对象,
并修改其空格值.不过,我确实做饭了:
类SetWhitespace(对象):
def __init __(自我, Whitespacechars):
self.whitespacechars = WhitespaceChars
def __call __(self,pyparsing_expr):
pyparsing_expr.setwhitespace(self.whitespacechars)
返回pyparsing_expr
nonlskipping = setWhitespace('\ t \ r')
word = nonlskipping(word(alpha))
我将在Wiki上发布此信息,看看我们得到了什么样的评论.
顺便说一下,setDefaultWhitespace仅更新全局变量
在解析器定义时间使用, *不 *在解析器分析时间.所以,
同样,您可以在初始化时管理此类属性
您的程序,在任何传入请求需要使用一个请求之前
解析器或另一个.
同时,我添加了这个.替换确实是一个方便的助手.
发布替换后,我收到了一个解析器的解析器
尚未在文档中读到" r",他
以这种简单的格式实现了同样的事情:
wellement = literal('kument').setParseaction(lambda:'<空>')
这些几乎相当于,我只是对Python有多容易感到震惊
也为我们做事!
您想要这两个中的哪一个?
它们是等效的,我都监视它们,您可以浏览
使用"讨论选项卡在线线程"或
SF上的邮件列表存档.使用哪个更容易让您工作
和.
欢呼,欢迎来到pyparsing!
- 保罗
# 回答4


保罗·麦奎尔(Paul McGuire)在2008年9月3日星期三06:12:47 -0700写道:那样,人们不需要设置一个可能会干扰其他在同一过程中运行的Pyparsers的grobal值.

我试图将您的TokenFactory类制作原型,但是一旦我到了
作为实现__getAttribute __返回相应的pyparsing
课堂,我看不到如何抓住该类生成的对象,
并修改其空格值.
我遇到了同样的问题,直到我想起我可以伪造__init_______________________________________
使用函数闭合.
我已经将pyparsing.py导入了带有补丁片的HG存储库,
是我的第一个补丁:
diff -r 12e2bbff259e pyparsing.py
--- a/pyparsing.py星期三9月3日09:40:09 2008 +0000
+++ b/pyparsing.py星期三9月3日14:08:15 2008 +0000
@@ -1400,9 +1400,38 @@
def __req __(自我,其他):
返回self ==其他
+类TokenFinder(类型):
+""""收集所有源自令牌""的类
+ token_classes = dict()
+ def __init __(Cls,Name,Bases,dict):
+#保存课程
+ tokenfinder.token_classes [cls .__ name __] = cls
+
+类WhitespaceTokenFactory(对象):
+ def __init __(self,whitespace):
+ self._whitespace = whitespace
+
+ def __getAttr __(self,name):
+"""获取此类的属性""".
+#检查是否有这样的令牌
+如果在tokenfinder.token_classes中名称:
+ token = tokenfinder.token_classes [name]
+#构建一个伪造构造函数的关闭
+ def _callable(*args,** kwargs):
+ obj = token(*args,** kwargs)
+#将空格设置在令牌上
+ obj.setwhitespacechar S(self._whitespace) +返回OBJ +#返回返回令牌实例的函数 +返回_可言 + else: + rish attributeError("'%s'对象没有属性'%s'"%( + WhitespaceTokenFactory .__名称__,名称)) 班级令牌(Parserelement): """抽象分析子类,用于定义原子匹配 图案.""" + __ metaclass__ = tokenfinder + def __init __(自我): 我使用元类来获取所有令牌 - 级别的新课程 可以通过工厂自动访问创建,而无需任何 附加注册. 哦,是的,会有更多补丁. 我目前正在编辑第二个 补丁,但我最好将其直接邮寄给您,因为它不是真的 这个列表很有趣. 问候, Marek

标签: python

添加新评论