pyparsing delimitedList(...,combine = True)给出不一致的结果

时间:2016-06-20 15:39:50

标签: pyparsing

我在Python 3.4中使用pyparsing == 2.1.5,我得到的结果似乎很奇怪:

word = Word(alphanums)
word_list_no_combine = delimitedList(word, combine=False)
word_list_combine = delimitedList(word, combine=True)
print(word_list_no_combine.parseString('one, two'))  # ['one', 'two']
print(word_list_no_combine.parseString('one,two'))  # ['one', 'two']
print(word_list_combine.parseString('one, two'))  # ['one']: ODD ONE OUT
print(word_list_combine.parseString('one,two'))  # ['one,two']

对我来说,为什么“组合”选项会导致列表中的某个部分在存在空间时被吞下,但是当它不存在时则不会被吞噬。这是一个pyparsing bug还是我错过了一些明显的东西?

2 个答案:

答案 0 :(得分:2)

看起来这是由于Combine()的行为,特别是它的默认“adjacent = True”选项,然后由delimitedList()使用:

class Combine(TokenConverter):
    """Converter to concatenate all matching tokens to a single string.
       By default, the matching patterns must also be contiguous in the input string;
       this can be disabled by specifying C{'adjacent=False'} in the constructor.
    """
    def __init__( self, expr, joinString="", adjacent=True ):
    # ...

def delimitedList( expr, delim=",", combine=False ):
    # ...
    dlName = _ustr(expr)+" ["+_ustr(delim)+" "+_ustr(expr)+"]..."
    if combine:
        return Combine( expr + ZeroOrMore( delim + expr ) ).setName(dlName)
    else:
        return ( expr + ZeroOrMore( Suppress( delim ) + expr ) ).setName(dlName)

所以可以通过替换来解决:

def delimitedListPlus(expr, delim=",", combine=False, combine_adjacent=False):
    dlName = str(expr) + " [" + str(delim) + " " + str(expr) + "]..."
    if combine:
        return Combine(expr + ZeroOrMore(delim + expr),
                       adjacent=combine_adjacent).setName(dlName)
    else:
        return (expr + ZeroOrMore(Suppress(delim) + expr)).setName(dlName)

答案 1 :(得分:2)

我建议你使用普通的uncombined分隔列表和自定义的解析操作,而不是修改pyparsing:

word_list_combine_using_parse_action = word_list_no_combine.copy().setParseAction(','.join)
print(word_list_combine_using_parse_action.parseString('one, two'))

将打印one,two