2015-04-02 6 views
3

У меня есть строка в переменной a, как показано ниже:Python - извлечение шаблона из строки с использованием регулярных выражений

a = 'foo(123456) together with foo(2468)' 

Я хотел бы использовать «повторно», чтобы извлечь как foo(123456) и foo(2468) из строки.

У меня есть два вопроса:

  1. Что правильное регулярное выражение для использования? foo(.\*), похоже, не работает, так как он обрабатывает 123456) вместе с foo(2468 как .*
  2. Как извлечь оба foo?
+0

Вам нужна не жадная версия. – pzp

ответ

4
import re 
pattern = re.compile(r'foo\(.*?\)') 
test_str = 'foo(123456) together with foo(2468)' 

for match in re.findall(pattern, test_str): 
    print(match) 

Две вещи:

  1. .*? ленивый квантор. Он ведет себя так же, как и жадный квантификатор (.*), за исключением того, что он пытается сопоставить наименьшее количество символов, которые могут идти слева направо по всей строке. Обратите внимание: если вы хотите совместить хотя бы один символ между круглыми скобками, вам нужно будет использовать .+?.

  2. Использование \( и \) вместо ( и ), потому что круглые скобки, как правило, используются в регулярных выражениях для обозначения групп захвата, так что если вы хотите, чтобы соответствовать круглые скобки в буквальном смысле, вы должны использовать экранирующий символ перед ними, который является обратной косой черты.

4

Вы можете использовать FindAll со следующим выражением: r'(foo\(\d+\))':

import re 

a = 'foo(123456) together with foo(2468)' 

for v in re.findall(r'(foo\(\d+\))', a): 
    print(v) 

Результат:

foo(123456) 
foo(2468) 

Ваш expressoin foo(.*) не работает из-за (). Вам нужно убежать от них, как я это делал выше.

+0

Спасибо, Marcin Что делать, если моя строка: a = 'foo (abcdef) вместе с foo (jqk)' Какое регулярное выражение следует использовать? – user3431399

+0

Используйте тот же самый, но вместо '\ d +' делайте то же, что и вы. + ' – Marcin

2

Просто использовать выражение нежадным WildCard .*?

import re 
a = 'foo(123456) together with foo(2468)' 
for v in re.findall(r'foo\(.*?\)', a): 
    print(v) 
3

Вы можете использовать отрицательный класс символов.

>>> a = 'foo(123456) together with foo(2468) foo(abcdef) together with foo(jqk)' 
>>> re.findall(r'\bfoo\([^()]*\)', a) 
['foo(123456)', 'foo(2468)', 'foo(abcdef)', 'foo(jqk)'] 

[^()]* Инвертированный символьный класс, который соответствует любому символу, но не ( или ), ноль или более раз.

1

Использование re.findall(r'foo\(.*?\)'). Обратные косые черты выходят из круглых скобок (которые имеют особое значение для обозначения группы в регулярном выражении), а знак вопроса делает совпадение выполненным не-жадным способом.