Как я могу построить регулярное выражение, которое имеет часть параметров

1

Как я могу создать регулярное выражение в python, которое может соответствовать всем следующим? где это "строка (a-zA-Z)", следуя пробелу, следуя 1 или нескольким 4 целым числам, которые разделяются запятой:

Пример:
someotherstring 42 1 48 17,
somestring 363 1 46 17,363 1 34 17,401 3 8 14,
otherstring 42 1 48 17,363 1 34 17,

Я пробовал следующее, так как мне нужно знать все целые числа:

myRE=re.compile("(\s+) ((\d+) (\d+) (\d+) (\d+),)+"

Но как я могу узнать, сколько у меня целых 4 целых чисел? и как я могу обработать каждый из них?

Спасибо.

  • 0
    Это сложнее, чем необходимо, потому что запятая используется как разделитель целых чисел и «единиц данных». Если вы легко можете повлиять на то, как выглядят ваши данные, я бы вместо этого использовал точку с запятой перед каждой строкой. Тогда достаточно использовать split , а не re.
Теги:

3 ответа

1
Лучший ответ
>>> test = "somestring 363 1 46 17,363 1 34 17,401 3 8 14,"

Здесь находится процессор pyparsing для вашей входной строки:

>>> from pyparsing import *
>>> integer = Word(nums)
>>> patt = Word(alphas) + OneOrMore(Group(integer*4 + Suppress(',')))

Использование patt.parseString возвращает объект parseResults pyparsing, который имеет некоторые хорошие свойства list/dict/object. Сначала просто распечатайте результаты в виде списка:

>>> patt.parseString(test).asList()
['somestring', ['363', '1', '46', '17'], ['363', '1', '34', '17'], ['401', '3', '8', '14']]

Посмотрите, как каждая из ваших групп группируется как подсписок?

Теперь пусть парсер сделает для нас немного больше работы. Во время разбора мы уже знаем, что мы анализируем действительные целые числа - любое совпадение Word(nums) должно быть целым числом. Поэтому мы можем добавить синтаксическое действие для этого преобразования во время разбора:

>>> integer = Word(nums).setParseAction(lambda tokens:int(tokens[0]))

Теперь мы воссоздаем наш шаблон, и теперь синтаксический анализ дает нам группы чисел:

>>> patt = Word(alphas) + OneOrMore(Group(integer*4 + Suppress(',')))
>>> patt.parseString(test).asList()
['somestring', [363, 1, 46, 17], [363, 1, 34, 17], [401, 3, 8, 14]]

Наконец, мы также можем назначить имена битам, которые были обработаны из этого ввода:

>>> patt = Word(alphas)("desc") + OneOrMore(Group(integer*4 + Suppress(',')))("numgroups")

Список возвращаемых элементов одинаковый:

>>> patt.parseString(test).asList()
['somestring', [363, 1, 46, 17], [363, 1, 34, 17], [401, 3, 8, 14]]

Но если мы дамп() результаты, мы видим, что мы можем получить по имени:

>>> print patt.parseString(test).dump()
['somestring', [363, 1, 46, 17], [363, 1, 34, 17], [401, 3, 8, 14]]
- desc: somestring
- numgroups: [[363, 1, 46, 17], [363, 1, 34, 17], [401, 3, 8, 14]]

Мы можем использовать эти имена для доступа к типу или атрибуту. Я частично отношусь к стилю атрибута:

>>> res = patt.parseString(test)
>>> print res.desc
somestring
>>> print res.numgroups
[[363, 1, 46, 17], [363, 1, 34, 17], [401, 3, 8, 14]]
>>> for ng in res.numgroups: print sum(ng)
...
427
415
426

Вот весь процессор анализатора и вывода:

test = "somestring 363 1 46 17,363 1 34 17,401 3 8 14,"
from pyparsing import *
integer = Word(nums).setParseAction(lambda tokens:int(tokens[0]))
patt = Word(alphas)("desc") + \
    OneOrMore(Group(integer*4 + Suppress(',')))("numgroups")

print patt.parseString(test).asList()
print patt.parseString(test).dump()
res = patt.parseString(test)
print res.desc
print res.numgroups
for ng in res.numgroups: 
    print sum(ng)
0
import re
str_in = "someotherstring 42 1 48 17, somestring 363 1 46 17,363 1 34 17,401 3 8 14, otherstring 42 1 48 17,363 1 34 17,"
list_out = re.split("[\\s,]", str_in)

list_out затем содержит список, в котором за именем каждого раздела следуют все целые числа (все еще как строки), затем пустая запись (полезна для разделов разделов) и т.д.:

['someotherstring', '42', '1', '48', '17', '', 'somestring', '363', '1', '46', '17', '363', '1', '34', '17', '401', '3', '8', '14', '', 'otherstring', '42', '1', '48', '17', '363', '1', '34', '17', '']
0

Поскольку ваши блоки данных (как я их называл выше) разделены запятой И пробелом, вы все равно можете использовать split:)

data = "someotherstring 42 1 48 17, somestring 363 1 46 17,363 1 34 17,401 3 8 14, otherstring 42 1 48 17,363 1 34 17"

data_items = data.split(', ')
for item in data_items:
    section_title, intdata = item.split(' ', 1)
    print 'Processing %s' % section_title
    for ints in intdata.split(','):
        a, b, c, d = [int(x) for x in ints.split()]
        # do your stuff ...

Ещё вопросы

Сообщество Overcoder
Наверх
Меню