2013-07-30 5 views
0

У меня есть строка:Python Regex - множественное выражение Match с группами

property1=1234, property2=102.201.333, property3=abc 

Я хочу, чтобы захватить 1234 и 102.201.333. Я пытаюсь использовать регулярное выражение:

property1=([^,]*)|property2=([^,]*) 

Но ему удалось захватить только одно из значений. На основании this link я также пытался:

((?:property1=([^,]*)|property2=([^,])+) 
(?:(property1=([^,]*)|property2=([^,])+) 

Они захватывают дополнительную группу из где-то я не могу понять.

Что мне не хватает?

P.S. Я использую re.search().

Edit: Там может быть что-то не так в моем вызывающем коде:

m = re.search('property1=([^,]*)|property2=([^,]*)', text); 
print m.groups() 

Edit2: Он не должен быть propertyX. Это может быть что угодно:

foo1=123, bar=101.2.3, foobar=abc 

даже

foo1=123, bar=weirdbar[345], foobar=abc 

ответ

1

Регулярные выражения отлично подходят для вещей, которые действуют как lexemes, что не так хорошо для синтаксического анализа общего назначения.

В этом случае, однако, это выглядит как ваша «Конфигурация-й строка» может состоять только из последовательности лексем вида: слова=значения [,слово=значения ...]. Если это так, вы можете использовать регулярное выражение и повторение. Правильное регулярное выражение зависит от точного вида слова и значение, хотя (и в меньшей степени, хотите ли вы проверить наличие ошибок). Например, есть:

this="a string with spaces", that = 42, quote mark = " 

разрешено, или нет? Если это так, то this установлен на a string with spaces (без кавычек) или "a string with spaces" (включает в себя кавычки)? Is that установлен на  42 (у которого есть ведущий пробел) или только 42 (что нет)? Разрешен ли quote mark (который имеет встроенные пространства) и установлен ли он на одну метку двойной кавычки? Есть ли двойные кавычки, если он присутствует, «бежать» запятые, так что вы можете написать:

greeting="Hello, world." 

Предполагая, что пространства запрещены, а слово и значение части просто «буквенно-цифровые, как совпадающая по \w»:

for word, value in re.findall(r'([\w]+)=([\w]+)', string): 
    print word, value 

это ясно из значения 102.201.333 что \w не является достаточной для value матча, хотя. Если значение является «все не запятая» (который включает в себя пробелы), затем:

for word, value in re.findall(r'([\w]+)=([^,]+)', string): 
    print word, value 

становится ближе. Все они игнорируют «мусор» и запрещают пробелы вокруг знака =. Если string является "$a=this, b = that, c=102.201.333,,", второй печатает for цикл:

a this 
c 102.201.333 

Доллар-знак (не алфавитно-цифровой символ) игнорируется, значение b игнорируется из-за белого пространства, и две запятые после значения для c также игнорируются.

+0

Ну мой UseCase и проще, и сложнее, чем это: Его проще, потому что: * property1, свойство2 (т.е. слово) известен и зашит * Я могу жить с некоторым количеством ошибок Это трудно, потому что * Значение может быть сложным (weirdbar [345, weirderbar [123]]) – SANDeveloper

+0

Я понял, что я пытаюсь сделать больше Deseriazlization, чем разбора регулярных выражений. Поэтому я вообще перехожу к другому подходу. Но я буду отмечать ваше решение как ответ за то, что он самый полный. – SANDeveloper

0

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

0

вы могли бы попробовать:

property_regex = re.compile('property[0-9]+=(?P<property_value>[^\s]+)') 

, что будет соответствовать любой собственности после знака равенства и перед пробелом. Она будет доступна из названия property_value так же, как говорится в документации:

скопирована из python re documentation

Например, если шаблон (P [A-Za-Z _] \ ш *?), То группа может быть , ссылаясь на свое имя в аргументах на методы объектов соответствия, таких как как m.group ('id') или m.end ('id'), а также по имени в обычном самом выражении (используя (? P = id)) и текст замены, указанный для .sub() (с использованием \ g).

0

попробовать это:

property_regex = re.compile('property[0-9]+=([^\s]+)') 
+0

lol это не то, что я ответил? – PepperoniPizza

+0

Извините, я упростил здесь. Это не должно быть свойствоX. Это может быть что угодно foo1 = 123, bar = 101.2.3, foobar = abc – SANDeveloper

1

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

text = "property1=1234, property2=102.201.333, property3=abc" 
data = dict(p.split('=') for p in text.split(', ')) 
print data["property2"] # '102.201.333' 
+0

Интересно, может использовать это как последнее средство. – SANDeveloper

0

Я пытался строить регулярное выражение для вас, которая даст вам значение после property1 = и свойство2, но я не знаю, как использовать их в Python.

Редактировать

в настоящее время захватывает другие вещи отдельно от имущества до знака символа '='.

Это мое оригинальное регулярное выражение, которое фиксирует значение.

(? < = [\ ш] =). *? [^] +

и это вариация выше, IMO, что я считаю, что вам нужно будет использовать в Python

/(?<=[\w]=).*?[^,]+/g 
Смежные вопросы