Пипарс: пространство как действительный токен

StackOverflow https://stackoverflow.com/questions/4598764

  •  15-10-2019
  •  | 
  •  

Вопрос

Я использую Pyparser для обработки вывода конвертера шестнадцатеричного текста. Он распечатывает 16 символов на строку, разделенные пространствами. Если значение шестнадцатеричного значения является символом ASCII, этот символ печатается, в противном случае преобразователь выводит период (.)

В основном выход выглядит так:

. a . v a l i d . s t r i n g .
. a n o t h e r . s t r i n g .
. e t c . . . . . . . . . . . .

Мой код пипарса для описания этой строки:

dump_line = 16 * Word(printables, exact=1)

Это работает нормально, пока конвертер шестигранного в текст не достигнет значения шестнадцатеричного значения 0x20, что заставляет его выводить пространство.

l i n e . w . a .   s p a c e .

В этом случае Pyparsing игнорирует выходное пространство и берет символы из следующей строки, чтобы сделать «квоту» из 16 символов.

Может ли кто -нибудь, пожалуйста, предложить, как я могу сказать Pyparsing, чтобы ожидать 16 символов, каждый из которых разделен пространством, где пространство также может быть действительным персонажем?

Заранее спасибо. Дж

Это было полезно?

Решение

Поскольку это имеет значительные пробелы, вам нужно сказать выражение своего персонажа, чтобы оставить ведущий пробел в одиночку. Посмотрите, как это сделано ниже в определении DumpChar:

hexdump = """\
. a . v a l i d . s t r i n g . 
. a n o t h e r . s t r i n g . 
. e t c . . . . . . . . . . . . 
l i n e . w . a .   s p a c e . 
. e t c . . . . . . . . . . . . 
"""

from pyparsing import oneOf, printables, delimitedList, White, LineEnd

# expression for a single char or space
dumpchar = oneOf(list(printables)+[' ']).leaveWhitespace()

# convert '.'s to something else, if you like; in this example, '_'
dumpchar.setParseAction(lambda t:'_' if t[0]=='.' else None)

# expression for a whole line of dump chars - intervening spaces will
# be discarded by delimitedList
dumpline = delimitedList(dumpchar, delim=White(' ',exact=1)) + LineEnd().suppress()

# if you want the intervening spaces, use this form instead
#dumpline = delimitedList(dumpchar, delim=White(' ',exact=1), combine=True) + LineEnd().suppress()

# read dumped lines from hexdump
for t in dumpline.searchString(hexdump):
    print ''.join(t)

Отпечатки:

_a_valid_string_
_another_string_
_etc____________
line_w_a_ space_
_etc____________

Другие советы

Подумайте о том, чтобы использовать другой способ удаления пробелов

>>> s=". a . v a l i d . s t r i n g ."
>>> s=s[::2]
>>> s
'.a.valid.string.'
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top