Регулярное выражение Python не соответствует http: // - PullRequest
6 голосов
/ 28 июля 2011

Я столкнулся с проблемой сопоставления и замены определенных слов, не содержащихся в http: //

Prege Rexx:

 http://.*?\s+

Это соответствует шаблону http://www.egg1.com <a href="http://www.egg2.com" rel="nofollow">http://www.egg2.com</a>

Мне нужно регулярное выражение для сопоставления с определенными словами, содержащимися вне http://

Пример:

"This is a sample. http://www.egg1.com and http://egg2.com. This regex will only match 
 this egg1 and egg2 and not the others contained inside http:// "

 Match: egg1 egg2

 Replaced: replaced1 replaced2

Окончательный вывод:

 "This is a sample. http://www.egg1.com and http://egg2.com. This regex will only 
  match this replaced1 and replaced2 and not the others contained inside http:// "

ВОПРОС: Необходимо сопоставить определенные шаблоны(как в примере: egg1 egg2), если они не являются частью http: //. Не сопоставляйте egg1 и egg2, если они присутствуют в http: //

Ответы [ 4 ]

6 голосов
/ 28 июля 2011

Одно из решений, которое я могу придумать, - сформировать комбинированный шаблон для HTTP-URL-адресов и вашего шаблона, а затем отфильтровать соответствия:

import re

t = "http://www.egg1.com http://egg2.com egg3 egg4"

p = re.compile('(http://\S+)|(egg\d)')
for url, egg in p.findall(t):
  if egg:
    print egg

отпечатков:

egg3
egg4

ОБНОВЛЕНИЕ: Чтобы использовать эту идиому с re.sub(), просто укажите функцию фильтра:

p = re.compile(r'(http://\S+)|(egg(\d+))')

def repl(match):
    if match.group(2):
        return 'spam{0}'.format(match.group(3))
    return match.group(0)

print p.sub(repl, t)

печать:

http://www.egg1.com http://egg2.com spam3 spam4
2 голосов
/ 28 июля 2011

Это не будет захватывать http://...:

(?:http://.*?\s+)|(egg1)
1 голос
/ 28 июля 2011

Вы должны предварять свой паттерн отрицательным взглядом за утверждением:

(?<!http://)egg[0-9]

В этом регулярном выражении каждый раз, когда механизм регулярных выражений находит шаблон, соответствующий egg[0-9], он будет оглядываться назад, чтобы проверить, не соответствуют ли предыдущие шаблоны http://. Отрицательное утверждение за задним числом начинается с (?<! и заканчивается ). Все, что находится между этими разделителями, не должно предшествовать следующему шаблону и не будет включено в результат.

Как использовать это в вашем случае:

>>> regex = re.compile('(?<!http://)egg[0-9]')
>>> a = "Example: http://egg1.com egg2 http://egg3.com egg4foo"
>>> regex.findall(a)
['egg2', 'egg4']
0 голосов
/ 28 июля 2011

Расширяя ответ Брандизи, я бы просто изменил его регулярное выражение на следующее:

(?<!http://[\w\._-]*)(egg1|egg2)
...