Причина, по которой ваш list
не анализируется, заключается в следующем выражении:
element = word | obj | list
Поскольку вы проверяете word
до list
(что является действительно ужасным именем переменной при работе в Python, кстати), тогда ведущий "foo" в "foo, bar" обрабатывается как word
, так как '|' является энергичным оператором, совпадающим с первым совпадающим выражением.
Это можно исправить, изменив порядок выражений в element
:
element = list | word | obj
Или используя '^' вместо '|'. '^' - оператор пациента - он оценивает все альтернативные выражения и выбирает самое длинное совпадение.
element = word ^ obj ^ list
При любом из этих изменений ваш вывод теперь становится:
word
list
word
list
obj
word
word
list
Почему все списки совпадают? Поскольку delimitedList
будет соответствовать одному элементу:
>>> wd = Word(alphas)
>>> wdlist = delimitedList(wd)
>>> print(wdlist.parseString('xyz'))
['xyz']
Если вы хотите, чтобы списки имели> 1 элемент, вы можете добавить действие разбора условия:
>>> wdlist.addCondition(lambda t: len(t)>1)
>>> print(wdlist.parseString('xyz'))
... raises exception ...
Кроме того, delimitedLists не группируют свои результаты автоматически:
>>> print((wd + wdlist).parseString('xyz abc,def'))
['xyz', 'abc', 'def']
Если вы хотите сохранить содержимое списка в виде списка в результатах, оберните выражение списка в группу:
>>> print((wd + Group(wdlist)).parseString('xyz abc,def'))
['xyz', ['abc', 'def']]
Вот моя обновленная версия вашего process()
метода:
def process(string):
print(string)
word = ~Literal('OBJ') + Word(alphas.lower())
word.addParseAction(lambda s,l,t: found_word(s, l, t))
word.setName("word")
obj = Literal('OBJ') + Word(alphas.lower())
obj.setName("obj")
obj.addParseAction(lambda s,l,t: found_obj(s, l, t))
item = word | obj
list = Group(pyparsing.delimitedList(item, delim=',')
.addCondition(lambda t: len(t)>1))
list.setName("list")
list.addParseAction(lambda s,l,t: found_list(s, l, t))
element = obj | list | word
parser = pyparsing.OneOrMore(element)
parser.searchString(string).pprint()
, который дает такой вывод:
foo bar OBJ baz foo,bar
word
word
word
word
obj
word
word
list
[['foo', 'bar', 'OBJ', 'baz', ['foo', 'bar']]]
Вы заметите, что я добавил setName()
вызовов для каждого ваших выражений. Это сделано для того, чтобы я мог добавить setDebug()
, чтобы получить отладочный вывод pyparsing. Добавив:
word.setDebug()
obj.setDebug()
list.setDebug()
перед вызовом parseString
, вы получите этот результат отладки. Это может помочь объяснить, почему вы получаете реплицированные «слова» в своем примере вывода.
foo bar OBJ baz foo,bar
Match obj at loc 0(1,1)
Exception raised:Expected "OBJ", found 'f' (at char 0), (line:1, col:1)
Match list at loc 0(1,1)
Match word at loc 0(1,1)
word
Matched word -> ['foo']
Exception raised:failed user-defined condition, found 'f' (at char 0), (line:1, col:1)
Match word at loc 0(1,1)
word
Matched word -> ['foo']
Match obj at loc 3(1,4)
Exception raised:Expected "OBJ", found 'b' (at char 4), (line:1, col:5)
Match list at loc 3(1,4)
Match word at loc 4(1,5)
word
Matched word -> ['bar']
Exception raised:failed user-defined condition, found 'b' (at char 4), (line:1, col:5)
Match word at loc 3(1,4)
word
Matched word -> ['bar']
Match obj at loc 7(1,8)
obj
Matched obj -> ['OBJ', 'baz']
Match obj at loc 15(1,16)
Exception raised:Expected "OBJ", found 'f' (at char 16), (line:1, col:17)
Match list at loc 15(1,16)
Match word at loc 16(1,17)
word
Matched word -> ['foo']
Match word at loc 20(1,21)
word
Matched word -> ['bar']
list
Matched list -> [['foo', 'bar']]
Match obj at loc 23(1,24)
Exception raised:Expected "OBJ", found end of text (at char 23), (line:1, col:24)
Match list at loc 23(1,24)
Match word at loc 23(1,24)
Exception raised:Expected W:(abcd...), found end of text (at char 23), (line:1, col:24)
Match obj at loc 23(1,24)
Exception raised:Expected "OBJ", found end of text (at char 23), (line:1, col:24)
Exception raised:Expected {word | obj}, found end of text (at char 23), (line:1, col:24)
Match word at loc 23(1,24)
Exception raised:Expected W:(abcd...), found end of text (at char 23), (line:1, col:24)
Match obj at loc 23(1,24)
Exception raised:Expected "OBJ", found end of text (at char 23), (line:1, col:24)
Match list at loc 23(1,24)
Match word at loc 23(1,24)
Exception raised:Expected W:(abcd...), found end of text (at char 23), (line:1, col:24)
Match obj at loc 23(1,24)
Exception raised:Expected "OBJ", found end of text (at char 23), (line:1, col:24)
Exception raised:Expected {word | obj}, found end of text (at char 23), (line:1, col:24)
Match word at loc 23(1,24)
Exception raised:Expected W:(abcd...), found end of text (at char 23), (line:1, col:24)
[['foo', 'bar', 'OBJ', 'baz', ['foo', 'bar']]]