Я пытаюсь проанализировать какой-то древний формат данных промышленного оборудования с использованием pyparsing
и столкнуться с поведением, которое я не понимаю.
Формат входной строки: R<x0>,<y0>,<w>,<h>[,*<level>];
, где x0, y0, w, h - действительные числа, уровень - целое число в диапазоне 1-8. Звездой отмечается наличие жетона уровня, и вся конструкция уровня может быть опущена, в этом случае по умолчанию используется значение 1
.
Я хочу, чтобы анализатор вывел список чисел, подобных этому [x0, y0, w, h, level]
с числами, преобразованными в соответствующие типы данных.
Парсер, который я написал, делает почти то же, что и я, с одним нюансом:
from pyparsing import Word, nums, ZeroOrMore, Suppress, Literal, Optional, Combine, StringEnd, srange
rtext = 'R.0,.2,5.7,.2,*1;'
# rtext = 'R0.0,0.2,5.7,0.2;'
real = Combine(ZeroOrMore(Word(nums)) + Literal('.') + Word(nums)).setParseAction(lambda s, l, t: float(t[0]))
level = Word(srange('[1-8]')).setParseAction(lambda s, l, t: int(t[0]))
rect_mark = Suppress('R')
comma = Suppress(',')
star = Suppress('*')
semicolon = Suppress(';')
level_str = Combine(star + level)
rect = rect_mark + real + comma + real + comma + real + comma + real + \
Optional(comma + level_str, default=1) + semicolon + StringEnd()
res = rect.parseString(rtext)
print(res) # => [0.0, 0.2, 5.7, 0.2, '1']
Почему жетон уровня не конвертируется в int
? Конечно, я могу преобразовать его на более позднем этапе обработки, но я бы предпочел, чтобы входные данные были согласованными.