2016-05-12 4 views
0

получил действительно странную проблему. Мой (Python) RegEx выглядит следующим образом:RegEx/Python: необязательный пробел не найден

u'^.*(?:Grundfl|gfl|wfl|wohnfl|whg|wohnung).*(\s\d{1,3}[.,]?\d{1,2}?)\s*(?:m\u00B2|qm)' 

В re.findall() - термин, это должно бросить два матча на следующий текст: "... от 71m² до 83m²" Однако только 83 соответствует. Проблема имеет какое-то отношение к необязательному пробелу между числом (\ s \ d {1,3} [.,]? \ D {1,2}?) И квадратными метрами (?: M \ u00B2 | qm), поскольку, когда я удаляю \ s *, только 71 соответствует ожидаемому. Я не знаю, что не так с моим регулярным выражением. Спасибо за помощь!

+1

вопрос несколько неясно: вы хотите, чтобы получить первый номер? Затем попробуйте ['^. * (?: Grundfl | gfl | ​​wfl | wohnfl | whg | wohnung). *? \ S (\ d {1,3} [.,]? \ D {1,2}?) \ s * (?: т \ u00B2 | QM) '] (https://regex101.com/r/iU2iV0/1). Вы не получите двух совпадений, потому что шаблон привязан в начале строки с '^'. Итак, попробуйте ['.. *? (?: Grundfl | gfl | ​​wfl | wohnfl | whg | wohnung). *? \ S (\ d {1,3} [.,]? \ D {1,2} ?) \ s * (? ?: м \ u00B2 | QM) (: \ з + к \ s + (\ d {1,3} \ d {1,2} [,.]?) \ s * (? : м \ u00B2 | QM)) '] (https://regex101.com/r/iU2iV0/3?). Или просто просто ['(\ d {1,3} [.,]? \ D {1,2}?) \ S * (?: M \ u00B2 | qm)'] (https://regex101.com/r/iU2iV0/4) –

+0

Я не могу воспроизвести это - удаление '\ s *' не изменяет соответствие: https://regex101.com/r/mO1rH2/1 - но кроме этого '' \ d {1,2}? 'не означает« соответствует 1 или 2 цифрам, необязательно »- в любом случае вам нужно' \ d {0,2} '. –

+0

Не удалось ли это вообще упростить: ['(\ d {1,2}) \ D + (\ d {1,2})'] (https://regex101.com/r/mO1rH2/2)? – Jan

ответ

0

Почему вы не пытаетесь использовать положительный взгляд? Это будет соответствовать 1 + цифрам (с дополнительной запятой внутри), если есть или qm после него. Существует дополнительное пространство между номерами и блоком:.

>>> import re 
>>> re.findall("[\d|\,]{1,}(?=\s{0,4}[m\u00B2|qm])", "from 71m² to 83m²") 
['71', '83'] 
>>> re.findall("[\d|\,]{1,}(?=\s{0,4}[m\u00B2|qm])", "from 71,56 m² to 837,78 qm") 
['71,56', '837,78'] 
>>> 

Он не принимает во внимание слова, которые вы указали, но вы можете легко добавить эту часть обратно в Однако re.findall() возвращает нон -overlapping, поэтому, если вы укажете начало строки в своем поиске, она только вернет первое значение, так как оно эффективно «отбивает» части, которые он соответствует, поэтому никогда не обнаруживает вторую часть.

+0

Ага, значит, во входной строке не может быть '100 м²'? Зачем принимать этот ответ, если он не учитывает поплавки или все целые числа? –

+0

Нет смысла использовать lookahead, поскольку вы можете использовать группу захвата с 're.findall'. –

+0

@ WiktorStribiżew Можете ли вы уточнить?Взгляд выглядит так, что он соответствует только числам, у которых есть единицы после этого, иначе любые случайные цифры в строке вернут совпадение. –

0

Вы можете использовать следующее регулярное выражение с re.findall:

(\d*[.,]?\d+)\s*(?:m\u00B2|qm) 

См regex demo. re.findall вернет только список захваченных значений группы 1.

Pattern деталь:

  • (\d*[.,]?\d+) - Группа 1, содержащая целое число или поплавок номера: 0+ цифры, а затем с 1 или 0 . или , следует с 1+ цифр
  • \s* - 0+
  • пробелов
  • (?:m\u00B2|qm) - либо , либо qm.

См Python demo:

# -*- coding: utf-8 -*- 
import re 
p = re.compile(u'(\d*[.,]?\d+)\s*(?:m\u00B2|qm)') 
s = u"wohnung from 71,556m² to 183.4456m²" 
print(p.findall(s)) # => [u'71,556', u'183.4456'] 
Смежные вопросы