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

How to refine that regex which skips one of two words?

我有一条短信,我想将所有 comprata、comprate、comprati、comprato 更改为 comprat+ 和所有 ricomprata、ricomprate、ricomprati、ricompratoricomprat+。所以我写了这个正则表达式,但它跳过了两个词之一:

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

结果是:

"ricomprat+ uno comprat+ comprata due comprat+ ricomprate tre ricomprat+ comprati"

由于尾部 (\s|) 模式占用了一个空格并阻止了连续匹配,因此您的正则表达式不起作用。

您可以使用像

这样的 PCRE 正则表达式
testo <- 'ricomprate uno comprato comprata due comprate ricomprate tre ricomprato comprati'
gsub('(?<!\S)((?:ri)?comprat)[aeio](?!\S)', '\1+', testo, perl=TRUE)
[1] "ricomprat+ uno comprat+ comprat+ due comprat+ ricomprat+ tre ricomprat+ comprat+"

参见 this regex demo详情:

  • (?<!\S) - 左侧空白边界
  • ((?:ri)?comprat) - 第 1 组:一个可选的 ri 字符串,然后是 comprat
  • [aeio](?!\S) - eaio 后跟右侧空白边界

或者,像

这样的 TRE 正则表达式
testo <- 'ricomprate uno comprato comprata due comprate ricomprate tre ricomprato comprati'
gsub('\b((?:ri)?comprat)[aeio]\b', '\1+', testo)
## => [1] "ricomprat+ uno comprat+ comprat+ due comprat+ ricomprat+ tre ricomprat+ comprat+"

参见R demo online and this regex demo,其中\b代表单词边界。

作为您可能使用的模式

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

Regex demo | R demo

在替换使用组1和一个+

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+"
base::gsub('comprat[aeio]', 'comprat+', testo)

输出

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