8

我有大量真实世界的文本,我需要从中提取单词以输入拼写检查器。我想在没有太多噪音的情况下提取尽可能多的有意义的单词。我知道这里有很多正则表达式忍者,所以希望有人可以帮助我。

目前我正在使用'[a-z]+'. 这是一个不错的近似值,但它会拖出很多垃圾。

理想情况下,我想要一些正则表达式(不一定要漂亮或高效)来提取由自然单词分隔符(例如[/-_,.: ]等)分隔的所有字母序列,并忽略任何具有非法边界的字母序列。

但是,我也很高兴能够获得所有不与数字相邻的字母序列。因此,例如'pie21'不会提取'pie',但'http://foo.com'会提取['http', 'foo', 'com']

我尝试lookaheadlookbehind断言,但它们是按字符应用的(例如,当我希望它什么都不re.findall('(?<!\d)[a-z]+(?!\d)', 'pie21')返回时会返回)。'pi'我尝试将 alpha 部分包装为一个术语 ( (?:[a-z]+)),但它没有帮助。

更多细节:数据是一个电子邮件数据库,所以它主要是带有普通数字的简单英语,但偶尔会有像我想完全忽略的垃圾GIHQ4NWL0S5SCGBDD40ZXE5IDP13TYNEA字符串AC7A21C0。我假设任何带有数字的字母顺序都是垃圾。

4

4 回答 4

18

如果您将自己限制为 ASCII 字母,则使用(带有re.I选项集)

\b[a-z]+\b

\b是一个单词边界锚,仅匹配字母数字“单词”的开头和结尾。所以\b[a-z]+\b匹配pie,但不是pie21or 21pie

要还允许其他非 ASCII 字母,您可以使用如下内容:

\b[^\W\d_]+\b

这也允许重音字符等。您可能需要设置该re.UNICODE选项,尤其是在使用 Python 2 时,以允许\w速记匹配非 ASCII 字母。

[^\W\d_]作为否定字符类,允许除数字和下划线以外的任何字母数字字符。

于 2011-04-19T14:25:35.683 回答
3

你熟悉单词边界吗?( \b)。\b您可以使用周围的序列提取单词并匹配其中的字母:

\b([a-zA-Z]+)\b

例如,这将抓取整个单词,但在连字符、句点、分号等标记处停止。

您可以在python 手册\b中查看序列和其他内容

编辑此外,如果您正在寻找比赛之后或之前的数字,您可以使用否定的前瞻/后视:

(?!\d)   # negative look-ahead for numbers
(?<!\d)  # negative look-behind for numbers
于 2011-04-19T14:26:31.970 回答
2

关于什么:

import re
yourString="pie 42 http://foo.com GIHQ4NWL0S5SCGBDD40ZXE5IDP13TYNEA  pie42"
filter (lambda x:re.match("^[a-zA-Z]+$",x),[x for x in set(re.split("[\s:/,.:]",yourString))])

注意:

  • split 将您的字符串分解为潜在的候选词 => 返回“潜在单词”列表
  • set 使唯一性过滤 => 转换 set 中的列表,从而删除多次出现的条目。此步骤不是强制性的。
  • filter 减少候选者的数量:获取一个列表,对每个元素应用一个测试函数,并返回一个通过测试的元素的列表。在我们的例子中,测试函数是“匿名的”
  • lambda : 匿名函数,获取一个项目并检查它是否是一个单词(仅限大写或小写字母)

编辑:添加了一些解释

于 2011-04-19T14:32:34.587 回答
0

示例代码

print re.search(ur'(?u)ривет\b', ur'Привет')
print re.search(ur'(?u)\bривет\b', ur'Привет')

或者

s = ur"abcd ААБВ"
import re
rx1 = re.compile(ur"(?u)АБВ")
rx2 = re.compile(ur"(?u)АБВ\b")
rx3 = re.compile(ur"(?u)\bАБВ\b")
print rx1.findall(s)
print rx2.findall(s)
print rx3.findall(s)
于 2017-12-06T10:44:31.387 回答