Regex, чтобы сопоставить 'lol' с 'lolllll' и 'omg' с 'omggg' и т. Д. - PullRequest
4 голосов
/ 09 октября 2010

Привет, я люблю регулярные выражения, но я совсем не хорош в них.

У меня есть список из 400 сокращенных слов, таких как lol, omg, lmao ... и т. Д. Всякий раз, когда кто-то печатает одно из этих сокращенных слов, оно заменяется его английским аналогом ([смех] или что-то в этом роде). В любом случае, люди раздражают и набирают эти короткие слова с повторением последней буквы (букв) x раз.

примеры: омг -> омгггл, лол -> лолллль, хаха -> хахахаха, лол -> лололол

Мне было интересно, может ли кто-нибудь передать мне регулярное выражение (желательно на Python), чтобы справиться с этим?

Спасибо всем.

(Это связанный с Twitter проект для определения темы, если кому-то любопытно. Если кто-то пишет в Твиттере «Давайте пойдем, сделаем несколько обручей», откуда вы знаете, что твит о баскетболе и т. Д.)

Ответы [ 2 ]

7 голосов
/ 09 октября 2010

ПЕРВЫЙ ПОДХОД -

Ну, используя регулярные выражения, вы можете сделать это так -

import re
re.sub('g+', 'g', 'omgggg')
re.sub('l+', 'l', 'lollll')

и т.д.

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

ВТОРОЙ ПОДХОД -

Вместо этого вы рассматривали возможность использования difflib модуля? Это модуль с помощниками для вычисления дельт между объектами. Здесь для вас особое значение имеет SequenceMatcher. Перефразируя из официальной документации -

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

import difflib as dl
x   = dl.SequenceMatcher(lambda x : x == ' ', "omg", "omgggg")
y   = dl.SequenceMatcher(lambda x : x == ' ', "omgggg","omg")
avg = (x.ratio()+y.ratio())/2.0
if avg>= 0.6: 
    print 'Match!'
else:
    print 'Sorry!'

Согласно документации, любое отношение () свыше 0,6 близко соответствует. Возможно, вам придется изучить настройку соотношения для ваших потребностей в данных. Если вам нужно более строгое соответствие, я нашел, что любое значение выше 0,8 хорошо подойдет.

3 голосов
/ 09 октября 2010

Как насчет

\b(?=lol)\S*(\S+)(?<=\blol)\1*\b

(заменить lol на omg, haha и т. Д.)

Это будет соответствовать lol, lololol, lollll, lollollol и т. Д., Но не выполнено lolo, lollllo, lolly и т. Д.

Правила:

  1. Совпадение со словом lol полностью.
  2. Затем разрешите любое повторение одного или нескольких символов в конце слова (т. Е. l, ol или lol)

То есть \b(?=zomg)\S*(\S+)(?<=\bzomg)\1*\b будет соответствовать zomg, zomggg, zomgmgmg, zomgomgomg и т. Д.

В Python, с комментариями:

result = re.sub(
    r"""(?ix)\b    # assert position at a word boundary
    (?=lol)        # assert that "lol" can be matched here
    \S*            # match any number of characters except whitespace
    (\S+)          # match at least one character (to be repeated later)
    (?<=\blol)     # until we have reached exactly the position after the 1st "lol"
    \1*            # then repeat the preceding character(s) any number of times
    \b             # and ensure that we end up at another word boundary""", 
    "lol", subject)

Это также будет соответствовать "неукрашенной" версии (т.е. lol без повторения). Если вы не хотите этого, используйте \1+ вместо \1*.

...