4

嘿,我喜欢正则表达式,但我根本不擅长它们。

我有一个大约 400 个缩写词的列表,例如 lol、omg、lmao 等。每当有人键入这些缩写词中的一个时,它就会被其英文对应词替换([笑声],或类似的东西)。无论如何,人们很烦人,并在最后一个字母重复 x 次的情况下键入这些速记词。

示例:omg -> omgggg,lol -> lollll,haha -> haha​​haha,lol -> lololol

我想知道是否有人可以将正则表达式(最好是在 Python 中)交给我来处理这个问题?

谢谢大家。

(如果有人好奇,这是一个与 Twitter 相关的主题识别项目。如果有人发推文“我们去打篮球”,你怎么知道推文是关于篮球的,等等)

4

2 回答 2

7

第一种方法 -

好吧,使用正则表达式你可以这样做 -

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

等等

让我指出,使用正则表达式是处理这个问题的一种非常脆弱和基本的方法。您可以很容易地从用户那里获取字符串,这将破坏上述正则表达式。我想说的是,这种方法需要大量维护,以观察用户所犯错误的模式,然后为他们创建特定于案例的正则表达式。

第二种方法——

相反,您是否考虑过使用difflib模块?它是一个带有帮助器的模块,用于计算对象之间的增量。对您来说特别重要的是SequenceMatcher. 从官方文档中解释-

SequenceMatcher 是一个灵活的类,用于比较任何类型的序列对,只要序列元素是可散列的。SequenceMatcher 尝试计算两个序列之间的“人类友好差异”。基本概念是最长 连续且无垃圾的匹配子序列。

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 的 ratio() 都是匹配的。您可能需要探索调整比率以满足您的数据需求。如果您需要更严格的匹配,我发现任何超过 0.8 的值都很好。

于 2010-10-09T06:10:18.437 回答
4

怎么样

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

(替换lolomghaha

这将匹配lol, lololol,等lolllllollollol但失败lolo,lollllololly

规则:

  1. 完全匹配单词lol
  2. 然后允许在单词末尾重复一个或多个字符(即lollol

所以\b(?=zomg)\S*(\S+)(?<=\bzomg)\1*\b将匹配zomg, zomggg,zomgmgmgzomgomgomg

在 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*.

于 2010-10-09T17:34:08.713 回答