2017-01-04 5 views
1

Я работаю над твитами о разных фильмах (используя API поиска в Twitter), и теперь я хотел заменить соответствие фиксированной строкой.Regex, чтобы найти и заменить имена фильмов python

Я боролся с «XMen Apocalypse», потому что есть много способов найти это в твитах. Я искал "XMEN Апокалипсиса", "XMen Апокалипсис", "X-Men Апокалипсис", "XMen", "XMen", "X-Men" и этим retrived меня совпадает также включает в себя "@xmenmovie", "#xmen", "X-Men: апокалипсис" и т.д ...

Это регулярное выражение, которое у меня есть:

xmen_regex = re.compile("(((#)x[\-]?men:?(apocalypse)?)|(x[\-]? ?men[:]?[ ]?(apocalypse)?))") 
def re_place_moviename(text, compiled_regex): 
    return re.sub(compiled_regex, "MOVIE_NAME", text.lower()) 

я испытал с RegExr, но до сих пор не является точным в некоторых крайних случаях, таких как: '#xmen BlaBla' -> заменить -> '#MOVIE_NAME BlaBla' или 'MOVIE_NAMEblabla'.

Итак, есть лучший способ сделать это? возможно, скомпилируйте другое регулярное выражение (при увеличении длины (?)) и применяя его отдельно?

редактировать

Сдерживает (или кратко):

  1. Я хочу, чтобы найти "Xmen", "х мужчин", "Xmen"
  2. Все 1 + "апокалипсис"
  3. Все 1 + ": апокалипсис"
  4. также: "#xmen", "# X-Men", "#xmenapocalypse", "# х-menapocalypse"
  5. Не должно быть подстроки («@xmenmovie» или «lovexmen perfect»), должно содержать как минимум 1 место в начале и в конце выражения.

PS: Другие фильмы проще, но xmen и другие, такие как Rogue One, имеют много способов выразить это, и мы хотим использовать его.

PS1: Я знаю, что \ б может помочь, но я не мог понять, как это работает.

ответ

1

Это необходимо сделать работу:

(?:^|\s)#x[ -]?men:?\s?apocalypse\b 

В случае замены, если вы хотите сохранить пространство перед тем, использовать захват группы и поместить его в сменной части:

(^|\s)#x[ -]?men:?\s?apocalypse\b 

Объяснение:

(?:^|\s) : non capture group, begining of string or a space 
#   : # 
x   : x 
[ -]?  : optional space or dash 
men   : men 
:?   : optional semicolon 
\s?   : optional space 
apocalypse : apocalypse 
\b   : word boundary 
+0

Спасибо! То же самое, что я пришел сегодня. Проблема в том, что я использую re.sub (regx, 'MOVIE'), «группу не захвата», которую он все еще заменяет. т. е. «jaja #xmen jaja» -> jajaMOVIE jaja –

+0

@OmarMiranda: вы можете использовать группу захвата '(^ | \ s)' и добавить ее в замещающую часть. – Toto

+0

jajaja спасибо !!! (^ | \ s) \ 0, поскольку замена делает трюк! :) –

0

Это должно работать в соответствии с вашими (неопределенных) ограничений: (?i)(?<![#@])x[- ]?men(?!:)(apocalypse)?

  • (?i) - игнорировать случай флаг
  • (?<![#@]) - нет # или @ до 'Xmen'
  • [- ]? - опционально - или
  • (?!:) - no colon after 'xmen'
  • (apocalypse)? - необязательный апокалипсис строка

Редактировать: Вместо того, чтобы требовать пробел перед/сзади, я думаю, имея границу (\b) будет более подходящим, то есть (?i)\b(?<[email protected])(x[- ]?men:?\s?(?:apocalypse)?)\b как «Xmen 'может начать предложение.

+0

Спасибо! Я добавил резюме, извините за то, что не был таким конкретным в первый раз :) –

+0

@OmarMiranda np! Добавлено несколько изменений – moogle

+0

Я изменяю (? I) \ b (?

Смежные вопросы