设计一个正则表达式来找到任何名词短语

10 投票
3 回答
7751 浏览
提问于 2025-04-18 10:50

我正在尝试用正则表达式(不使用NLTK)来构建一个分块器(或者说是浅层解析器),但是我找不到合适的正则表达式来实现我的目标。我的直接目标是:在自然语言文本中找到所有名词短语。

我的第一步是用我自己制作的词性标注器给所有句子打上标签,然后把这些标记和单词的列表合并成一个字符串,像这样:

'he PRN and CC bill NP could MOD hear VB them PRN on IN the DT large JJ balcony NN near IN the DT house NN'

接下来的步骤是用正则表达式在这个字符串中查找名词短语的实例。一般来说,名词短语的结构是:一个可选的限定词(DT),零个或多个形容词(JJ),以及一个名词(NN)、专有名词(NP)或代词(PRN)。根据这个通用结构,我尝试了这个正则表达式(请记住,标记字符串中的单词和标签是交替出现的):

'(\w+ DT)? (\w+ JJ)* (\w+ (NN|NP|PRN))'

这是我的代码:

text = 'he PRN and CC bill NP could MOD hear VB them PRN on IN the DT large JJ balcony NN near IN the DT house NN'

regex = re.compile(r'(\w+ DT)? (\w+ JJ)* (\w+ (NN|NP|PRN))')
m = regex.findall(text)

if m:
     print m

这是我的输出结果:

[('the DT', 'large JJ', 'balcony NN', 'NN')]

它没有找到代词或专有名词,而且出于某种原因,只匹配了'NN'在'\w+ DT \w+ NN'这个模式中。我本以为我的正则表达式会匹配这些模式,因为我把限定词的模式设为可选(?),把形容词的模式设为零个或多个(*)。

Chris

3 个回答

0

一般的语言公式

在抓取名词短语时会遇到一些问题。

名词短语可以包含连词、副词,并且可以用包含动词的从句进行后修饰,那么动名词该怎么处理呢?

比如说“真的好人和卖给我那本他们有出售的书的女人” = 这就是一个名词短语。

还有“本地、国家和国际的慈善机构” = 这是一串形容词。

不过,可能先找出那些不是动词或介词的东西会更简单一些。(记住,短语也可以嵌套在其他短语里面)

^V^I

0

你的正则表达式应该是:

(\w+ DT)? (\w+ JJ)*|(\w+ (?:NN|NP|PRN))

示例

7

使用这个:

(?:(?:\w+ DT )?(?:\w+ JJ )*)?\w+ (?:N[NP]|PRN)

可以查看这个示例

  • (?:(?:\w+ DT )?(?:\w+ JJ )*)? 是一个可选的匹配方式,它可以匹配一个名词前的限定词(DT),后面跟着零个或多个形容词。
  • '\w+ (?:N[NP]|PRN)' 用来匹配名词(NN)、名词短语(NP)或者代名词(PRN)。

撰写回答