quanteda会找到与正则表达式不匹配的字符串

人工智能 2026-07-09

考虑下面的示例:

library(quanteda)
testcorpus <- c(
  "I play the piano",
  "He plays the piano",
  "They played the piano",
  "I play the saxophone",
  "I play the Roland piano"
)
tokenized <- tokens(testcorpus)
kk <- kwic(tokenized, phrase(c("\\bplay the piano\\b")), valuetype = "regex")
print(kk)

它的输出是:

Keyword-in-context with 3 matches.                                        
 [text1, 2:4]    I |  play the piano  | 
 [text2, 2:4]   He | plays the piano  | 
 [text3, 2:4] They | played the piano |

为什么它找到了 "plays the piano" 和 "played the piano"?

正则表达式本不应该匹配这两个。

我并不是说这是我不想要的行为。事实上,我甚至可能会想要它。

但我想要的是(1)理解它为什么会找到它们,以及(2)理解如何按原样匹配这个正则表达式。

解决方案

phrase() 将字符串(s) 按其 separator=" " 分割,因此你的内部调用返回

phrase(c("\\bplay the piano\\b"))
# [[1]]
# [1] "\\bplay"  "the"      "piano\\b"

这里有两点需要注意:(1)"\\bplay" 将对任何以 "play" 开头的标记进行匹配(因此是 "plays" 和 "played");以及(2)你假设这是一个完整的三词短语,而不是分开的词。注意,将分隔符改成其他东西并不一定会达到你所期望的效果:

phrase(c("\\bplay the piano\\b"), "|")
# [[1]]
# [1] "\\bplay the piano\\b"
kwic(tokenized, phrase(c("\\bplay the piano\\b"), "|"), valuetype = "regex")
# Keyword-in-context with 0 matches.

这是因为 tokenized 由若干词的序列组成,而不是句子:

tokenized
# Tokens consisting of 5 documents.
# text1 :
# [1] "I"     "play"  "the"   "piano"
# text2 :
# [1] "He"    "plays" "the"   "piano"
# text3 :
# [1] "They"   "played" "the"    "piano" 
# text4 :
# [1] "I"         "play"      "the"       "saxophone"
# text5 :
# [1] "I"      "play"   "the"    "Roland" "piano"

不过,如果你在每个词上放置正则表达式的单词边界,我们可以得到一些结果:

kwic(tokenized, phrase(c("\\bplay\\b \\bthe\\b \\bpiano\\b")), valuetype = "regex")
# Keyword-in-context with 1 match.                                   
#  [text1, 2:4] I | play the piano |
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。