2016-12-14 13 views
-1

Я хотел бы регулярное выражение Python, которое соответствует заданному слову, которое не находится между простыми кавычками. Я попытался использовать (?! ...), но безуспешно.Регулярное выражение: совпадение слова не между кавычками

На следующем скриншоте я хотел бы сопоставить все foe, за исключением одного в 4-й строке.

Плюс, текст дается как одна большая строка.

Вот ссылка regex101 и образец текст ниже:

var foe = 10; 
foe = ""; 
dark_vador = 'bad guy' 
foe = ' I\'m your father, foe ! ' 
bar = thingy + foe 
+1

Опубликовать свой код проверки –

+2

Вы не можете указать реальную ссылку на regex101, а не на экран? – RomanPerekhrest

+3

Не размещайте скриншот - не редактируйте в коде. –

ответ

1

Решение регулярное выражение ниже будет работать в большинстве случаев, но это может сломаться, если несбалансированные одиночные кавычки появляются за пределами строки литералы, например в комментариях.

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

Вот пример Python демо:

import re 
rx = r"('[^'\\]*(?:\\.[^'\\]*)*')|\b{0}\b" 
s = r""" 
    var foe = 10; 
    foe = ""; 
    dark_vador = 'bad guy' 
    foe = ' I\'m your father, foe ! ' 
    bar = thingy + foe""" 
toReplace = "foe" 
res = re.sub(rx.format(toReplace), lambda m: m.group(1) if m.group(1) else 'NEWORD', s) 
print(res) 

Смотрите в Python demo

Регулярное выражение будет выглядеть

('[^'\\]*(?:\\.[^'\\]*)*')|\bfoe\b 

См regex demo.

('[^'\\]*(?:\\.[^'\\]*)*') часть захватывает Ingle кавычки строковых литералов в 1-е группы, и если они совпадают, это просто положить обратно в результат, и \bfoe\b матчей целых слов foe в любом другом контексте строки - и впоследствии заменяется другим словом.

ПРИМЕЧАНИЕ: Чтобы также совместить литералы с двойными кавычками, используйте r"('[^'\\]*(?:\\.[^'\\]*)*'|\"[^\"\\]*(?:\\.[^\"\\]*)*\")".

+0

Спасибо, он отлично работает! – Liquiid

+0

Рад, что это сработало для вас. Пожалуйста, подумайте о том, чтобы принять ответ, щелкнув ✓ слева (см. [Как принять ответы SO] (http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work)). –

1

Как насчет this регулярного выражения:

>>> s = '''var foe = 10; 
foe = ""; 
dark_vador = 'bad guy' 
' I\m your father, foe ! ' 
bar = thingy + foe''' 
>>> 
>>> re.findall(r'(?!\'.*)foe(?!.*\')', s) 
['foe', 'foe', 'foe'] 

Хитрости здесь, чтобы убедиться, что выражение не соответствует ни одной строке с начальным и конечным ' и помнить, чтобы учитывать символы между ними, а затем .* в выражении re.

+0

Это не будет трюк с первого врага в враге = «Я твой отец, враг! 'должно быть сопоставлено =' ( – Liquiid

+0

@ Liquiid, вы сказали, что он не должен совпадать между одинарными кавычками ?, так почему же он должен совпадать? –

+0

In foe = '..... foe .... 'он должен соответствовать только первому, потому что ii не в кавычках. – Liquiid

1

Вы можете попробовать это: -

((?!\'[\w\s]*)foe(?![\w\s]*\'))

+0

Это не работает для me on regex101 – Liquiid

1

enter image description here

((?!\'[\w\s]*[\\']*[\w\s]*)foe(?![\w\s]*[\\']*[\w\s]*\')) 
+0

Это не работает, если оно соответствует враг между двумя кавычками. = '( – Liquiid

+0

@ Liquiid: Не утруждайтесь этими ответами. Lookarounds вам не помогут. –