Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 通常在pyparsing中展平返回的列表_Python_Grammar_Text Parsing_Pyparsing - Fatal编程技术网

Python 通常在pyparsing中展平返回的列表

Python 通常在pyparsing中展平返回的列表,python,grammar,text-parsing,pyparsing,Python,Grammar,Text Parsing,Pyparsing,这一部分的解释有点冗长,所以请记住:我必须分析许多文本部分,如: first multi segment part 123 45 67890 third multi segment part ------------^----------- -----^------ ------------^----------- Part A: alpha words B: num words Part C: alpha words 我尝试对每个部分使用pp.OneOrMore: a = p

这一部分的解释有点冗长,所以请记住:我必须分析许多文本部分,如:

first multi segment part 123 45 67890 third multi segment part

------------^----------- -----^------ ------------^-----------
  Part A: alpha words    B: num words   Part C: alpha words
我尝试对每个部分使用
pp.OneOrMore

a = pp.OneOrMore(pp.Word(pp.alphas)).setName("PART_A")('A')
b = pp.OneOrMore(pp.Word(pp.nums)).setName("PART_B")('B')
c = pp.OneOrMore(pp.Word(pp.alphas)).setName("PART_C")('C')
expr = a + b + c
当我在字符串“first multi-segment part 123 45 67890 third multi-segment part”(第一个多段部分123 45 67890第三个多段部分)上运行此命令时,我得到

- A: ['first', 'multi', 'segment', 'part']
- B: ['123', '45', '67890']
- C: ['third', 'multi', 'segment', 'part']
但是,我希望所有的结果都像:

- A: 'first multi segment part'
- B: '123 45 67890'
- C: 'third multi segment part'
为此,我可以使用
setParseAction
函数。因为我将有很多使用此功能的构造,所以我扩展了
一个或多个
类,如下所示:

class OneOrMoreJoined(pp.OneOrMore):
    """OneOrMore with results joined to one string"""
    def __init__( self, expr, stopOn=None, joinString=' '):
        super(OneOrMoreJoined,self).__init__(expr, stopOn=stopOn)
        self.setParseAction(joinString.join)
通过这门课,我得到了想要的结果。:-)

但是,如果我想加入序列
d1+d2
,我该怎么办

d1 = pp.Word(pp.nums).setName("PART_D1")
d2 = pp.Word(pp.alphas).setName("PART_D2")
expr = (d1 + d2)('D')
当然,我可以创建一个新类
和joined
,并使用
和joined(d1,d2)
,但随后我松开了漂亮的符号
d1+d2


有没有一个通用的方法来平展结果我当然可以在检索dict后在外部手动展平ParseResult,但我怀疑在
pyparsing
内部有一种简单的方法来表达这一点。

最简单的方法是编写一个如下的小助手:

joiner = lambda expr: expr.addParseAction(' '.join)
然后在语法中插入
joiner

a_b_c = joiner(a + b + c | d + Optional(e))
只需确保传递给
joiner
的令牌只是单级令牌。如果它们是嵌套的,那么您可能需要一个扁平化例程,但是通过将
joiner
编写为以下代码可以轻松地添加这一例程:

joiner = lambda expr: expr.addParseAction(flatten, ' '.join)

如果单词之间有多个空格,您希望结果只有一个空格,还是与原始字符串中的空格相同?所有空格都应缩小为单个空格(如
OneOrMoreJoined
类应该这样做)。我喜欢这种方法-它保持语法干净!但是函数
flatte
在哪里定义?这是留给学生的练习。好的,只是想检查是否有一个(递归的)
flatte
预定义的地方…这起作用:
def flatte(x):if-isinstance(x,six.string\u类型):返回x-elif-not-isinstance(x,collections.Iterable):return“”else:flatten_list=[flatten_to_string(e)for e in x]return”“。join((f for f in flatten_list if f!='')joiner=lambda expr:expr.addParseAction(flatte)
(抱歉,SE不允许在注释中使用缩进的代码块。)“展平和加入”可能是一个更好的名称,因为它同时执行两个任务。此外,如果不可iterable,可能返回
str(x)
,因为结果中可能有一个非字符串不可iterable值(如int)。