用于解析包含'v。'的标题的pyparsing语法

时间:2013-10-03 22:48:38

标签: python parsing pyparsing

我正在考虑解析表单的标题

<left part> v. <right part>

使用pyparsing。左侧部分可以是包含字母数字字符的名称,包括utf-8字符和标点符号。左侧部分允许v.本身。但是,中间的v.始终与空格分开。

可以为这种情况定义语法吗?

我做出的努力:

name = Word(alphas)
part1 = OneOrMore(name).setParseAction(lambda tokens:" ".join(tokens))
part2 = OneOrMore(name)
v_en = Word("v.").suppress()
v_fr = Word("c.").suppress()
versus = v_en 

expression = part +  versus + part2

效果不佳,因为左侧部分允许使用标点符号(并且只能在第一个点之前工作)

2 个答案:

答案 0 :(得分:2)

你嫁给了使用pyparsing的想法吗?因为如果你不是,那么你可以使用python内置功能快速解决你的问题,假设如下:

'v。'不会出现在

对于给定的标题,请尝试:

>>> pattern = ' v. '
>>> title.rsplit(pattern, 1)

,例如,

>>> 'this is a v. simple test'.rsplit(pattern, 1)
['this is a', 'simple test']
>>> 'A more v. complicated v. example'.rsplit(pattern, 1)
['A more v. complicated', 'example']

答案 1 :(得分:1)

如果您只是发布两个由“v。”分隔的团队名称,如“加利福尼亚大学诉圣母大学”,那么您可以通过几种不同的方式解析。

无法工作的一种方法是使用Word,就像您在帖子中一样。 Word旨在指定不是特定的文字,而是指定由特定字符串中的字符组成的单词组。例如,如果您尝试解析所有大写字母的首字母缩写词,那么您可以将其定义为:

acronym = Word(alphas.upper())

这将匹配“GE”,“IBM”,“CIA”,“FBI”等。

Word("blah")将匹配“bah”,“hal”,“bbba”,“hhhbbll” - 任何由字母“b”,“l”,“a”或“h”组成的单词组。在您的帖子中,Word("v.")将匹配“vvvv”,“....”,“v.v.v.v” - 包含v和。的任何相邻组。要定义文字“v。”,您实际上是在考虑LiteralKeyword

我认为,

Keyword确实是最合适的解决方案。 Keyword超过Literal的目的是Keyword添加了解析后的字符仅包含给定文字的约束,并且不能将任何其他常用字符相邻。因此Literal("who")会匹配“谁”的主要部分,但Keyword("who")则不会。

因此,要解析该示例文本,最简单的方法是使用SkipTo

from pyparsing import Keyword, SkipTo, restOfLine
test = "Univ. of Calif. v. Univ. of Notre Dame"
vs = Keyword("v.")

matchup = SkipTo(vs)("team1") + vs + restOfLine("team2")

print matchup.parseString(test).dump()

如果您想更加具体地了解您的团队,可以尝试这样的事情:

from pyparsing import Keyword, Combine, OneOrMore, Word, alphas
vs = Keyword("v.")
teamWord = Word(alphas+".")
teamName = Combine(OneOrMore(teamWord), " ", adjacent=False)
matchup = teamName("team1") + vs + teamName("team2")

print matchup.parseString(test).dump()

但这会给你这个例外

pyparsing.ParseException: Expected "v." (at char 38), (line:1, col:39)

就像现在一样,分离“v。”匹配作为有效的团队词。在构建团队单词之前,您需要包含一个负向前瞻,以便“v。”不会被误认为是。

teamWord = ~vs + Word(alphas+".")

将打印出来:

['Univ. of Calif.', 'v.', 'Univ. of Notre Dame']
- team1: Univ. of Calif.
- team2: Univ. of Notre Dame