【问题标题】:Negative lookbehind in RegEx: Matching multiple POS-tags at onceRegEx 中的负向回溯:一次匹配多个 POS 标签
【发布时间】:2021-08-06 19:45:04
【问题描述】:

我对正则表达式还是很陌生,所以我将不胜感激。 我正在尝试使用正则表达式在使用 CLAWS7 标记集进行词性标记的文本语料库中查找特定的语法模式。 这是一个示例:

Ya_UH and_CC then_RT uhm_NN1 we_PPIS2 wrote_VVD in_RP but_CCB already_RR taken_VVN up_RP that_DD1 day_NNT1 that_CST we_PPIS2 wanted_VVD actually_RR they_PPHS2 said_VVD still_RR available_JJ you_PPY know_VV0 so_RR by_II that_DD1 time_NNT1 we_PPIS2 we_PPIS2 write_VV0 in_II our_APPGE letter_NN1 two_MC weeks_NNT2 later_RRR already_RR taken_VVN up_RP Quite_RG good_RR uh_UH P ICE-SIN: S1A-001#74:1:B Ask_VV0 her_PPHO1 I_PPIS1 left_VVD my_APPGE house_NN1 at_II one_MC1 met_VVD PRO_NN1 in_II school_NN1 at_II two_MC Ya_PPY so_RR waited_VVD you_PPY know_VV0 they_PPHS2 say_VV0 half_DB hour_NNT1 later_RRR And_CC and_CC it_PPH1 was_VBDZ still_RR 下毛毛雨_JJ 和_CC 下雨_VVG

我正在寻找的模式是\w*\_V.*?(= 每个动词)的每个实例,不是前面有代词。代词可以有这些标签:

_PN _PN1 _PNQO _PNQS _PNQV _PNX1 _PPGE _PPH1 _PPHO1 _PPHO2 _PPHS2 _PPIO1 _PPIO2 _PPIS1 _PPIS2 _PPX1 _PPX2 _PPY

在示例中,所需的正则表达式应理想匹配:

taken_VVN
met_VVD 
Ask_VV0
waited_VVD
raining_VVG

使用否定的lookbehind,我设法创建了以下表达式,它只匹配前面没有_PPIS2标签的动词:

(?<!\_PPIS2)\s\w*\_V.*?

如何将其扩展到所有其他代词标签?我尝试了下面的表达式,但它们要么根本不匹配任何东西,要么匹配错误的实例。

(?<!\_P.*)\s\w*\_V.*? (no match)
(?<![\_P.*])\s\w*\_V.*? (wrong results)

任何想法或解释将不胜感激。

【问题讨论】:

  • 我正在使用 Sublime Text 3。
  • 试试\b(?:[^\W_]+_[^\W_]+ )?(?&lt;!_PN |_PN1 |_PNQ[OVS] |_PNX1 |_PPGE |_PPH1 |_PPHO[12] |_PPHS2 |_PPIO[12] |_PPIS[12] |_PPX[12] |_PPY )[^\W_]*_V\w*,见demo
  • 我已经编辑了帖子;很抱歉造成混乱。

标签: regex tags linguistics negative-lookbehind


【解决方案1】:

你可以使用

\b(?:[^\W_]+_[^\W_]+ )?(?<!_PN |_PN1 |_PNQ[OVS] |_PNX1 |_PPGE |_PPH1 |_PPHO[12] |_PPHS2 |_PPIO[12] |_PPIS[12] |_PPX[12] |_PPY )[^\W_]*_V\w*

请参阅regex demo

详情

  • \b - 单词边界
  • (?:[^\W_]+_[^\W_]+ )? - 可选序列
    • [^\W_]+ - 一个或多个字母/数字
    • _ - 下划线
    • [^\W_]+ - 一个或多个字母/数字和一个空格
  • (?&lt;!_PN |_PN1 |_PNQ[OVS] |_PNX1 |_PPGE |_PPH1 |_PPHO[12] |_PPHS2 |_PPIO[12] |_PPIS[12] |_PPX[12] |_PPY ) - 如果上述任何模式立即出现在当前位置的左侧,则匹配失败
  • [^\W_]* - 零个或多个数字/字母
  • _V - _V 字符串
  • \w* - 任何零个或多个单词字符。

【讨论】:

    【解决方案2】:

    你可以在 sublime 中使用这个 PCRE 正则表达式:

    \b\w*_P\w*\h+\w*_V\w*(*SKIP)(*F)|\b\w*_V\w*
    

    RegEx Demo

    正则表达式详细信息:

    • \b\w*_P\w*:匹配包含_P的单词
    • \h+: 匹配 1+ 个空格
    • \w*_V\w*:在任何地方匹配一个词与_V
    • (*SKIP)(*F): 跳过匹配的子串并失败
    • |:或者
    • \b\w*_V\w*:在任何地方用_V匹配一个词(这些是我们的匹配项)

    【讨论】:

      【解决方案3】:

      也许会有更智能的模式,但使用 Sublime Text 3,您可以使用 (*SKIP)(*F) 的组合首先匹配您不想要的内容,丢弃匹配的内容,然后匹配您想要的内容:

      _P(?:N(?:X?1|Q[OSV]|)|P(?:GE|H1|(?:[HI]O|IS|X)[12]|HS2|Y))\s\w+_V[A-Z0-9]*\b(*SKIP)(*F)|\w+_V[A-Z0-9]*\b
      

      查看在线demo。由于您的所有单词都以下划线结尾,后跟适当的语法模式,我认为它应该符合您的需求。

      【讨论】:

        最近更新 更多