【问题标题】:How to match binomial expressions in R?如何匹配R中的二项式表达式?
【发布时间】:2020-07-06 10:46:30
【问题描述】:

我想匹配二项式,即双音节词,有时连字符,音节重复略有不同;变体总是与重复音节中的第一个(也可能是第二个)字母有关:

x <- c("pow-wow", "pickwick", "easy-peasy", "nitty-gritty", "bzzzzzzz", "mmmmmm", "shish", "wedged", "yaaaaaa")

在这里,我们在pow-wow、pickwick、easy-peasy 和nitty-gritty 中说过音节重复(这就是预期的输出),但在bzzzzzzz、@ 中不是 987654330@、shish、wedged 和 yaaaaa。

这个正则表达式通过要求捕获组中存在元音,至少设法摆脱了wedged(发音为一个音节)以及单音节词:

grep("\\b\\w?((?!ed)(?=[aeiou])\\w{2,})-?\\w\\w?\\1\\b$", x, value = T, perl = T)
[1] "pow-wow"      "pickwick"     "easy-peasy"   "nitty-gritty" "yaaaaa" 

不过,yaaaaa 也在匹配中。 不匹配它我的感觉是捕获组应该被禁止包含两个相同的元音立即连续但我不知道如何实现该限制。 有什么想法吗?

【问题讨论】:

  • 试试"\\b\\w(?!(.)\\1|ed)(\\w{2,})-?\\w\\w?\\2\\b",见demo。如果重复部分的第一个字母必须是元音,试试"\\b\\w(?!(.)\\1|ed)([aeiou]\\w+)-?\\w\\w?\\2\\b"(见demo)
  • 非常好!为什么"\\b\\w?(?!(.)\\1|ed)([aeiou]\\w+)-?\\w\\w?\\2\\b" 不匹配choochoo("\\b\\w(?!(.)\\1|ed)(\\w{2,})-?\\w\\w?\\2\\b" 匹配)?
  • 也许你只想排除重复的字符,如果它们后面没有右边的相同值? "\\b\\w{0,2}(?!((.)\\2+)(?!.*\\1)|ed)([aeiou]\\w+)-?\\w\\w?\\3\\b",见demo
  • 是的,太好了。这也得到了wee-wee,这是以前的正则表达式没有的!您是否愿意将此作为答案发布并添加一些解释,因为这现在非常复杂,我和其他人肯定想从中学习?

标签: r regex regex-lookarounds


【解决方案1】:

如果在字符串更远的位置找不到相同的块,您似乎想要匹配在初始字符和 2 个或更多重复字符之后不能包含 ed 的单词。另外,开始和中间允许的“差异”窗口是 0 到 2 个字符。

你可以使用

\b\w{0,2}(?!((.)\2+)(?!.*\1)|ed)([aeiou]\w+)-?\w\w?\3\b

见regex demo

详情

  • \b - 单词边界(如果您的“单词”等于整个字符串,则可以使用 ^)
  • \w{0,2} - 两个或更多单词字符(替换为 \p{L} 以仅匹配字母)
  • (?!((.)\2+)(?!.*\1)|ed) - 不允许 ed 或两个或多个在字符串后面不重复的相同字符紧挨当前位置的右侧
  • ([aeiou]\w+) - 一个元音(在第 3 组中捕获)和 1 个以上的单词字符(替换为 \p{L} 以仅匹配字母)
  • -? - 可选连字符
  • \w\w? - 1 或 2 字字符
  • \3 - 与第 3 组中捕获的值相同
  • \b - 单词边界(如果您的“单词”等于整个字符串,则可以使用 $)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-03
    • 2020-12-24
    相关资源
    最近更新 更多