регулярное выражение Python для повторения строки - PullRequest
2 голосов
/ 11 января 2011

Я хочу проверить, а затем проанализировать эту строку (в кавычках):

string = "start: c12354, c3456, 34526; other stuff that I don't care about"
//Note that some codes begin with 'c'

Я хотел бы убедиться, что строка начинается с 'start:' и заканчивается ';' После этого я бы хотел, чтобы регулярное выражение анализировало строки. Я попробовал следующий код Python:

regx = r"start: (c?[0-9]+,?)+;" 
reg = re.compile(regx)
matched = reg.search(string)
print ' matched.groups()', matched.groups()

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

Или я должен отказаться от использования регулярных выражений?

РЕДАКТИРОВАТЬ: обновлено, чтобы отразить часть проблемного пространства, которое я пренебрег и фиксированная разница строк. Спасибо за все предложения - в такой короткий срок.

Ответы [ 4 ]

5 голосов
/ 11 января 2011

Вы можете использовать стандартные инструменты для работы со строками, которые почти всегда более читабельны.

s = "start: c12354, c3456, 34526;"

s.startswith("start:") # returns a boolean if it starts with this string

s.endswith(";") # returns a boolean if it ends with this string

s[6:-1].split(', ') # will give you a list of tokens separated by the string ", "

5 голосов
/ 11 января 2011

В Python это невозможно с одним регулярным выражением: каждый захват группы переопределяет последний захват этой же группы (в .NET это было бы на самом деле возможно, так как механизм различает записи и группы).

Самое простое решение - сначала извлечь часть между start: и ; и затем использовать регулярное выражение для возврата всех совпадений, а не только одногосопоставить, используя re.findall('c?[0-9]+', text).

2 голосов
/ 12 января 2011

Это можно сделать (довольно элегантно) с помощью такого инструмента, как Pyparsing :

from pyparsing import Group, Literal, Optional, Word
import string

code = Group(Optional(Literal("c"), default='') + Word(string.digits) + Optional(Literal(","), default=''))
parser = Literal("start:") + OneOrMore(code) + Literal(";")
# Read lines from file:
with open('lines.txt', 'r') as f:
    for line in f:
        try:
            result = parser.parseString(line)
            codes = [c[1] for c in result[1:-1]]
            # Do something with teh codez...
        except ParseException exc:
            # Oh noes: string doesn't match!
            continue

Более чистый, чем регулярное выражение, возвращает список кодов (не нужно string.split) и игнорирует любые дополнительные символы в строке, как в вашем примере.

0 голосов
/ 11 января 2011
import re

sstr = re.compile(r'start:([^;]*);')
slst = re.compile(r'(?:c?)(\d+)')

mystr = "start: c12354, c3456, 34526; other stuff that I don't care about"
match = re.match(sstr, mystr)
if match:
    res = re.findall(slst, match.group(0))

приводит к

['12354', '3456', '34526']
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...