regex - 如何在 nltk 语法中直接使用单词
问题描述
我正在尝试使用 python NLTK 从给定的德国地址中提取公司名称。这是我使用的代码,
import nltk
address="CompanyName GmbH * Keltenstr. 16 * 123456 Kippenheim * Deutschland"
tokens = nltk.word_tokenize(address)
textTokens = nltk.Text(tokens)
POStagList = nltk.pos_tag(textTokens)
print(POStagList)
grammar = """
NP:
{<NN.?|JJ|FW>GmbH}"""
cp = nltk.RegexpParser(grammar)
result = cp.parse(POStagList)
for subtree in result.subtrees(filter=lambda t: t.label() == 'NP'):
print("NP Subtree:", subtree)
我需要输出:CompanyName GmbH
有时,它可能不是GmbH ,而是corp或Inc.或llc等
如何解决这个问题?
如何在语法中直接使用字符串值和转义序列字符?
解决方案
除了将语法与文字字符串混合之外,您还可以使用正则表达式来解决:用 POS 标记标记,然后只在已知单词(如GmbH
)之前获取您需要的标记。
代码看起来像
import nltk
import re
address="CompanyName GmbH * Keltenstr. 16 * 123456 Kippenheim * Deutschland"
tokens = nltk.word_tokenize(address)
textTokens = nltk.Text(tokens)
POStagList = nltk.pos_tag(textTokens)
joined = ' '.join(["{}<{}>".format(word,tag) for word,tag in POStagList])
grammar = r'NN[^>]?|JJ|FW' # regex!
print([re.sub("<(?:{})>".format(grammar), "", x.strip()) for x in re.findall(r'((?:\S+<(?:{0})> )+)(?:GmbH|Inc|corp|llc)<(?:{0})>'.format(grammar), joined)])
输出:['CompanyName']
。
在这里,语法是使用正则表达式指定的,例如NN[^>]?|JJ|FW
where[^>]?
匹配任何 char but >
(只是为了确保我们不匹配>
,就像.
会那样)。之后,((?:\S+<(?:NN[^>]?|JJ|FW)> )+)(?:GmbH|Inc|corp|llc)<(?:NN[^>]?|JJ|FW)>
正则表达式将找到您需要的所有匹配项,但由于它们包含标签,因此必须使用re.sub
仅使用<(?:NN[^>]?|JJ|FW)>
正则表达式的 a 来删除它们。
主要的正则表达式细节:
((?:\S+<(?:NN[^>]?|JJ|FW)> )+)
- 第 1 组:一个或多个 1+ 非空白字符序列,后跟<
,然后NN
+ 任何 1 或 0 个除>
, 或JJ
或以外的字符FW
,>
然后是空格(?:GmbH|Inc|corp|llc)
- 任何备选方案:GmbH
、Inc
或corp
llc
<(?:NN[^>]?|JJ|FW)>
-<
, + 除, or或之外的NN
任何 1 或 0 个字符。>
JJ
FW
推荐阅读
- node.js - 如何在graphql中进行Daynamic突变?
- reactjs - process.env 未定义,我无法从中读取变量
- r - 为什么根据我在 R 中应用 group_by() 和 distinct() 的时间会得到不同的频率?
- r - 基于特定公差带的密度图(标准化)
- angular - 我如何用 rxjs 聚合数据对象?
- cross-compiling - x86_64-w64-mingw32-gcc 在 linux 子系统上交叉编译 usrsctp 会出现没有行号的错误
- julia - 如何在 Julia REPL 中搜索以前执行的命令?
- ios - 在 iOS 中注册 Flutter 插件
- python - 从数据框python调用值
- android - Room - 通用基类中的查询(尤其是流查询)