Применить несколько отрицательных регулярных выражений к выражению в Python - PullRequest
1 голос
/ 11 апреля 2009

Этот вопрос похож на "Как кратко каскадировать несколько операторов регулярных выражений в Python" за исключением того, что вместо сопоставления одного регулярного выражения и выполнения чего-то мне нужно убедиться, что я не сопоставляю кучу регулярных выражений , и если совпадений не найдено (иначе у меня есть действительные данные), тогда сделайте что-нибудь. Я нашел один способ сделать это, но думаю, что должен быть лучший способ, особенно если я получу много регулярных выражений.

По сути, я фильтрую URL-адреса на предмет плохих вещей ("", \\ "и т. Д.), Которые возникают, когда я вынимаю из HTML-документа то, что похоже на действительный URL-адрес, но оказывается частью JavaScript (и таким образом, необходимо оценить и, следовательно, экранировать символы). Я не могу использовать Beautiful soup для обработки этих страниц, поскольку они далеки от искажений (на самом деле я использую BeautifulSoup, а затем возвращаюсь к своему уродливому, но работающему парсеру).

До сих пор я обнаружил, что следующие работы относительно неплохо работают: я скомпилирую dict или регулярные выражения вне основного цикла (так что мне нужно скомпилировать его только один раз, но я получаю выгоду от увеличения скорости каждый раз, когда я его использую), тогда я Зацикливание URL-адреса в этом диктовке: если есть совпадение, то URL-адрес плохой, если нет - хороший URL-адрес

regex_bad_url = {"1" :   re.compile('\"\"'),
                 "2" :   re.compile('\\\"')}

Далее:

url_state = "good"

for key, pattern in regex_bad_url_components.items():
    match = re.search(pattern, url)
    if (match):
        url_state = "bad"

if (url_state == "good"):
# do stuff here ...

Теперь очевидной мыслью является использование регулярного выражения "или" ("|"), т. Е .:

re.compile('(\"\"|\\\")')

Что уменьшает количество сравнений и еще много чего, но значительно затрудняет поиск неисправностей (с одним выражением на сравнение я могу легко добавить выражение для печати, например:

print "URL: ", url, " matched by key ", key

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

Обновление:

Хороший ответ Дейва Уэбба, поэтому фактический код для этого будет выглядеть так:

match = re.search(r'(?P<double_quotes>\"\")|(?P<slash_quote>\\\")', fullurl)
if (match == None):
    # do stuff here ...
else:
    #optional for debugging
    print "url matched by", match.lastgroup

1 Ответ

2 голосов
/ 11 апреля 2009

"Squoosh" всех регулярных выражений в одну строку, но поместите каждого в именованную группу, используя (?P<name>...), затем используйте MatchOjbect.lastgroup, чтобы найти подходящее.

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