Поиск и захват символа с использованием регулярных выражений Python - PullRequest
2 голосов
/ 15 ноября 2010

Проходя одну из проблем в Python Challenge , я пытаюсь решить ее следующим образом:

Прочитать ввод в текстовом файле с символами следующим образом:

DQheAbsaMLjTmAOKmNsLziVMenFxQdATQIjItwtyCHyeMwQTNxbbLXWZnGmDqHhXnLHfEyvzxMhSXzd
BEBaxeaPgQPttvqRvxHPEOUtIsttPDeeuGFgmDkKQcEYjuSuiGROGfYpzkQgvcCDBKrcYwHFlvPzDMEk
MyuPxvGtgSvWgrybKOnbEGhqHUXHhnyjFwSfTfaiWtAOMBZEScsOSumwPssjCPlLbLsPIGffDLpZzMKz
jarrjufhgxdrzywWosrblPRasvRUpZLaUbtDHGZQtvZOvHeVSTBHpitDllUljVvWrwvhpnVzeWVYhMPs
kMVcdeHzFZxTWocGvaKhhcnozRSbWsIEhpeNfJaRjLwWCvKfTLhuVsJczIYFPCyrOJxOPkXhVuCqCUgE
luwLBCmqPwDvUPuBRrJZhfEXHXSBvljqJVVfEGRUWRSHPeKUJCpMpIsrV.......

Мне нужно пройти через этот текстовый файл и выбрать все строчные буквы, которые заключены только в три заглавные буквы с каждой стороны.

Сценарий python, который я написал для выполнениявышеприведенное выглядит следующим образом:

import re

pattern = re.compile("[a-z][A-Z]{3}([a-z])[A-Z]{3}[a-z]")
f = open('/Users/Dev/Sometext.txt','r')
for line in f:
    result = pattern.search(line)
    if result:
       print result.groups()

 f.close()

Приведенный выше сценарий вместо возврата захвата (списка символов в нижнем регистре) возвращает все текстовые блоки, которые соответствуют критериям регулярного выражения, например

aXCSdFGHj
vCDFeTYHa
nHJUiKJHo
.........
.........

Может кто-нибудь сказать мне, что именно я делаю здесь неправильно?И вместо того, чтобы перебирать весь файл, есть ли альтернативный способ выполнить поиск по регулярному выражению по всему файлу?

Спасибо

Ответы [ 3 ]

2 голосов
/ 15 ноября 2010

Я бы предложил использовать lookaround:

(?<=[A-Z]{3})(?<![A-Z].{3})([a-z])(?=[A-Z]{3})(?!.{3}[A-Z])

Это не будет иметь проблем с перекрывающимися совпадениями.

Объяснение:

(?<=[A-Z]{3})  # assert that there are 3 uppercase letters before the current position
(?<![A-Z].{3}) # assert that there is no uppercase letter 4 characters before the current position
([a-z])        # match a lowercase character (all characters in the example are ASCII)
(?=[A-Z]{3})   # assert that there are 3 uppercase letter after the current position
(?!.{3}[A-Z])  # assert that there is no uppercase letter 4 characters after the current position
2 голосов
/ 15 ноября 2010

Измените result.groups() на result.group(1), и вы получите только однобуквенное совпадение.

Вторая проблема с вашим кодом заключается в том, что он не найдет несколько результатов в одной строке. Поэтому вместо использования re.search вам понадобится re.findall или re.finditer. findall возвращает строки или кортежи строк, тогда как finditer возвращает объекты соответствия.

Вот где я подошел к той же проблеме:

import urllib
import re    

pat = re.compile('[a-z][A-Z]{3}([a-z])[A-Z]{3}[a-z]')
print ''.join(pat.findall(urllib.urlopen(
    "http://www.pythonchallenge.com/pc/def/equality.html").read())) 

Обратите внимание, что re.findall и re.finditer возвращают непересекающиеся результаты. Таким образом, при использовании вышеуказанного шаблона с re.findall поиском по строке 'aBBBcDDDeFFFg' ваше единственное совпадение будет 'c', но не 'e'. К счастью, в этой задаче Python Challenge таких примеров нет.

1 голос
/ 15 ноября 2010
import re

with open('/Users/Dev/Sometext.txt','r') as f: 
    tokens = re.findall(r'[a-z][A-Z]{3}([a-z])[A-Z]{3}[a-z]', f.read())

    for token ins tokens:
        print token

Что делает findall:

Возвращает все непересекающиеся совпадения шаблона в строке в виде списка строк.Строка сканируется слева направо, и совпадения возвращаются в указанном порядке.Если в шаблоне присутствует одна или несколько групп, вернуть список групп;это будет список кортежей, если шаблон имеет более одной группы.Пустые совпадения включаются в результат, если они не касаются начала другого совпадения.

Возможно, самая полезная функция в модуле re.

Функция read () читаетвесь файл в большую строку.Это особенно полезно, если вам нужно сопоставить регулярное выражение со всем файлом.

Предупреждение : В зависимости от размера файла, вы можете предпочесть итерацию по файлу построчно, какВы сделали в своем первом подходе.

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