R 如何改进跳过两个单词之一的正则表达式?

R 如何改进跳过两个单词之一的正则表达式?,r,regex,gsub,R,Regex,Gsub,我有一个文本,我想将所有compata、comprate、compati、comprato更改为comprat+,将所有ricomprata、ricomprati、ricomprato更改为ricomprat+。所以我写了这个正则表达式,但它跳过了两个单词中的一个: testo <- 'ricomprate uno comprato comprata due comprate ricomprate tre ricomprato comprati' base::gsub('(\\s|^)(r

我有一个文本,我想将所有compata、comprate、compati、comprato更改为comprat+,将所有ricomprata、ricomprati、ricomprato更改为ricomprat+。所以我写了这个正则表达式,但它跳过了两个单词中的一个:

testo <- 'ricomprate uno comprato comprata due comprate ricomprate tre ricomprato comprati'
base::gsub('(\\s|^)(ri|)comprat[aeio](\\s|)', '\\1\\2comprat+\\3', testo)

由于尾部的
(\s |)
模式使用空格并阻止连续匹配,因此正则表达式无法工作

您可以使用PCRE正则表达式,如

testo
看。详情:

  • (?-左侧空白边界
  • ((?:ri)?comprat)
    -第1组:可选
    ri
    字符串,然后
    comprat
  • [aeio](?!\S)
    -要么
    e
    a
    i
    要么
    o
    后跟右侧空白边界
或者,像treregex一样的

testo[1]“ricomprat+uno comprat+comprat+due comprat+ricomprat+tre ricomprat+comprat+”

请参见and,其中
\b
表示单词边界。

作为您可能使用的模式

\b((?:ri)?comprat)[aeio]\b
  • \b
    防止部分匹配的单词边界
  • 捕获组1(在替换中称为
    \\1
    • (?:ri)?
      可选择匹配
      ri
    • comprat
      Match
      comprat
  • 关闭第1组
  • [aeio]
    匹配列出的任何字符
  • \b
    单词边界
|

在更换中,使用组1和a
+

testo <- 'ricomprate uno comprato comprata due comprate ricomprate tre ricomprato comprati'
base::gsub('\\b((?:ri)?comprat)[aeio]\\b', '\\1+', testo)
输出

[1] "ricomprat+ uno comprat+ comprat+ due comprat+ ricomprat+ tre ricomprat+ comprat+"
[1] "ricomprat+ uno comprat+ comprat+ due comprat+ ricomprat+ tre ricomprat+ comprat+"

谢谢,Pietro!在这种情况下,它是有效的。但一般来说,它不会检查左侧空白。你必须展示一个相关的最小示例和预期输出,以证明你的意思。是的,你完全正确!谢谢,Wiktor!现在我明白了原因!非常清楚!谢谢,第四只鸟!非常全面回答得真好!
base::gsub('comprat[aeio]', 'comprat+', testo)
[1] "ricomprat+ uno comprat+ comprat+ due comprat+ ricomprat+ tre ricomprat+ comprat+"