2014-01-31 3 views
2

У меня есть следующий питона код, который будет пытаться прочитать входной файл и найти следующие экземпляры дают регулярное выражение:Regular Expression Python

[fF][eE][bB]([1-2][0-9]|[0-9] 

Я написал следующий код Python

#!/usr/bin/python 
import re 
import sys 

textFile = open(sys.argv[1], 'r') 
fileText = textFile.read() 
textFile.close() 
matches = re.findall("[fF][eE][bB] ([1-2][0-9]|[0-9])",fileText) 
print matches 

и мой входной файл:

1 2 3 the 
the quick 2354 
feb 1 
feb 0 
feb -10 
feb23 
feb 29 
feb 3 
february 10 

Однако, когда я запускаю мой код я получаю следующее Выход: ['1','29', '3']

Я хочу, чтобы мой выход, чтобы больше походить ['feb 1', 'feb 29', 'feb 3']

Я не совсем уверен, что я делаю неправильно. Любая помощь будет принята с благодарностью.

ответ

1

Вам нужно скобки вокруг всего выражения, чтобы matches содержал согласованный текст. Для каждой пары парен будет одна группа матчей; вы можете использовать (feb (?:[12][0-9]|[1-9])) для группировки без захвата для второй группы.

Однако, учитывая ваши примеры, возможно, вы действительно хотите распечатать всю строку ввода, когда есть совпадение?

+0

Заметен также '1-9', чтобы избежать согласований' февраля 0' , Если вы хотите также сопоставить это выражение, выражение может быть упрощено до '(feb [12]? [0-9])'. – tripleee

+0

Да, 're.IGNORECASE' тоже. – tripleee

1

Если вы хотите печатать, как это,

['feb 1', 'feb 29', 'feb 3'] 

Вы можете использовать следующий код,

matches = re.findall("(feb (?:[12][0-9]|[1-9]))",fileText) 
    print matches 
3

Вы должны read the documentation. re.findall возвращает только группы захвата, если они есть в выражении. Вы должны просто удалить группу захвата из вашего регулярного выражения:

matches = re.findall("[fF][eE][bB] (?:[1-2][0-9]|[0-9])",fileText) 
            ^^ 

Тем не менее, это регулярное выражение также будет соответствовать feb 0, так что вы можете захотеть использовать

[fF][eE][bB] (?:[1-2][0-9]|[1-9]) 
          ^

Вместо.

Теперь вы можете сделать регулярное выражение короче, если вы используете re.IGNORECASE (чтобы регулярное выражение соответствовало как прописным, так и строчным символам), и если вы используете цикл для чтения содержимого файла (это более эффективно для больших файлов). Кроме того, это хорошая практика, чтобы сырье вашей модели регулярных выражений:

with open(sys.argv[1], 'r') as textFile: 
    for line in textFile: 
     matches = re.match(r"feb (?:[1-2][0-9]|[1-9])", line, re.IGNORECASE) 
     if matches: 
      print matches.group() 

И, конечно же, вы можете поместить матчи в списке тоже, если вам нужен список, в конце концов.

+0

+1 Удивительный пост, он содержит столько информации, большая часть из которых уже мне известна, но больше, чем ожидалось, было неизвестно. Благодаря! – PascalVKooten

+0

@PascalvKooten Добро пожаловать :) – Jerry

0

Как насчет:

(feb\s[1-9][0-9]?) 

спичек: æÅ затем пробел и цифры от 1 до 9, а затем любой другой по желанию цифр от 0 до 9.

Try:

matches = re.findall(r'(feb\s[1-9][0-9]?)',fileText) 
print matches 
>>> ['feb 1', 'feb 29', 'feb 3'] 

Оговорка: это не решит для текста, как "FEB 51"

See it in action