【问题标题】:Finding the rhyming words in a corpus with R, regex使用 R,正则表达式在语料库中查找押韵词
【发布时间】:2021-01-13 21:29:41
【问题描述】:

我有以下语料库:

corpus_rhyme <- c("helter-skelter", "lovey-dovey", "riff-raff", "hunter-gatherer", 
                  "day-to-day", "second-hand", "chock-a-block")

在所有这些词中,我只需要像“helter-skelter”、“lovey-dovey”和“chock-a-block”这样的词,它们是押韵的重复词,辅音有变化。它们通常用连字符拼写,并且在元素之间可能有中间成分,例如“chock-a-block”中的“a”。我只需要找到具有相同音节数的押韵重复表达。例如,虽然 "phoney-baloney" 是押韵的重复词,但我不需要它。

我正在使用以下代码来查找押韵的重复词:

rhyme<- grep("\\b(\\w*)(\\w{2,}?)-(\\w{1,}?-)?\\w*\\2\\b", corpus_rhyme,
             ignore.case = TRUE, perl = TRUE, value = TRUE)

此代码产生太多误报。输出如下:

rhyme
[1] "helter-skelter"  "lovey-dovey"     "riff-raff"       "hunter-gatherer" "day-to-day"      "second-hand"    
[7] "chock-a-block"

我手动筛选出这些误报,这需要太多时间。谁能建议这行代码的更好版本以减少误报的数量?例如,出现“riff-raff”是因为我希望在重复表达式的末尾至少有 2 个最后的字母相同,否则我会错过像“rat-tat”这样的表达式。但是我们能否在这段代码中指定这两个字母必须彼此不同,以便找到“rat-tat”(“a”与“t”不同),但找到“riff-raff”(“f”和“f”是一样的)不出现? 另一个可能的改进:我怎样才能摆脱像“日常”这样两个元素完全相同的词?我只需要在初始辅音上有差异的押韵重复词。 最后,我不确定是否可以对“hunter-gatherer”做任何事情,除非有办法计算音节数并确保表达式的两个元素具有相同的音节数。

【问题讨论】:

  • 鉴于您正在寻找韵律,使用发音词典是否也有用? github.com/trevorld/r-cmudict 包括几个不同种类的英语。它对所有语料库术语没有帮助,但它可能有助于消除发音词典中的误报。

标签: r regex corpus linguistics false-positive


【解决方案1】:

Base R 解决方案,很可能有更简单的方法:

# Count the number of hyphens in each element: hyphen_count => integer vector
hyphen_count <- lengths(regmatches(corpus_rhyme, gregexpr("\\-", corpus_rhyme)))

# Check if the expression rhymes: named logical vector => stdout(console)
vapply(ifelse(hyphen_count == 1, 
      gsub('^[^aeiouAEIOU]+([aeiou]+\\w+)\\s*\\-[^aeiouAEIOU]+([aeiou]+\\w+)', '\\1 \\2', corpus_rhyme),
      gsub('^[^aeiouAEIOU]+([aeiou]+\\w+)\\s*\\-\\w+\\-[^aeiouAEIOU]+([aeiou]+\\w+)', '\\1 \\2', corpus_rhyme)
), function(x){
    split_string <- unlist(strsplit(x, "\\s"))
    identical(split_string[1], split_string[2])
  }, logical(1)
)

数据:

corpus_rhyme <- c("helter-skelter", "lovey-dovey", "riff-raff", "hunter-gatherer", 
                  "day-to-day", "second-hand", "chock-a-block")

【讨论】:

    【解决方案2】:

    如果第一个单词的后三个或更多字母与最后一个单词的后三个或更多字母相同是普遍现象,那么你可以试试这个:

    grep(".*(\\w{3,})-([aeiou]-)?(\\w+)(\\1)", corpus_rhyme,ignore.case = TRUE,value=TRUE)
    
    #[1] "helter-skelter" "lovey-dovey"    "chock-a-block"
    

    【讨论】:

      猜你喜欢
      • 2020-08-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多