量词可以用于R中的正则表达式替换吗?

Posted

技术标签:

【中文标题】量词可以用于R中的正则表达式替换吗?【英文标题】:Can quantifiers be used in regex replacement in R? 【发布时间】:2021-02-12 02:34:21 【问题描述】:

我的目标是将字符串替换为与字符串一样多的字符重复的符号,在某种程度上,如果我的模式是 "...(*)...",我可以将字母替换为大写字母 \\U\\1(*) 捕获的字符类似于x\\q1\\q1x,所以我会得到很多x 作为* 捕获的字符。

这可能吗?

我主要在sub,gsub 中思考,但您可以使用其他库如stringi,stringr 等来回答。 您可以使用perl = TRUEperl = FALSE 以及任何其他方便的选项。

我认为答案可能是否定的,因为选项似乎非常有限 (?gsub):

a replacement for matched pattern in sub and gsub. Coerced to character if possible. For fixed = FALSE this can include backreferences "\1" to "\9" to parenthesized subexpressions of pattern. For perl = TRUE only, it can also contain "\U" or "\L" to convert the rest of the replacement to upper or lower case and "\E" to end case conversion. If a character vector of length 2 or more is supplied, the first element is used with a warning. If NA, all elements in the result corresponding to matches will be set to NA. 

主要的量词是 (?base::regex):

?

    The preceding item is optional and will be matched at most once.
*

    The preceding item will be matched zero or more times.
+

    The preceding item will be matched one or more times.
n

    The preceding item is matched exactly n times.
n,

    The preceding item is matched n or more times.
n,m

    The preceding item is matched at least n times, but not more than m times.

好的,但它似乎是一个选项(不在PCRE 中,不确定是否在PERL 或在哪里......)(*) 捕获星量词能够匹配的字符数(我在https://www.rexegg.com/regex-quantifier-capture.html 找到它)所以可以使用\q1(相同的参考)来指代第一个捕获的量词(和\q2 等)。我还读到 (*) 等同于 0, 但我不确定这是否真的是我感兴趣的事实。

编辑更新

由于评论者的提问,我用this interesting question 提供的具体示例更新了我的问题。我修改了一下这个例子。假设我们有a <- "I hate extra spaces elephant",所以我们有兴趣保持单词之间的唯一空格,每个单词的前 5 个字符(直到这里作为原始问题),然后是每个其他字符的点(不确定这是否是什么预计在原始问题中但没关系)所以结果字符串将是"I hate extra space. eleph..."s 中的最后一个.spaces 中的最后一个ant 3 个点) elephant)。所以我首先将前 5 个字符保留为

gsub("(?<!\\S)(\\S5)\\S*", "\\1", a, perl = TRUE)
[1] "I hate extra space eleph"

我应该如何将\\S* 中的确切字符数替换为点或任何其他符号?

【问题讨论】:

请显示具体问题,包括输入和预期输出。 您可以使用regexpr 确定匹配位置和长度,然后使用substr&lt;- 替换它。所以这可能是实现目标的好方法。但如果您的问题是“现有的正则表达式函数是否有能力”,答案是否定的。 您发布的是 XY 问题。必须有其他方法来解决这个问题,顺便问一下,它是什么? \\L\\1 将小写,而不是大写 Group 1 值。我想你问的是gsub("(?:\\G(?!^)|\\()\\K[^()](?=[^()]*\\))", "x", "(888) 45 78 44", perl=TRUE)之类的问题,请参阅ideone.com/etIb9S 你的问题会更好,如果你编辑它的紧密性我很感激你已经对此进行了研究,但在答案中引用帮助页面通常比在问题中更合适。说“我”在?base::regex 上读过关于量词的内容可能就足够了,但没有发现任何关于在替换中使用它们的信息。 @G.Grothendieck 我用具体问题编辑了我的问题 【参考方案1】:

量词不能在替换模式中使用,也不能提供它们匹配多少个字符的信息。

您需要一个\G base PCRE pattern 来查找字符串中特定位置之后的连续匹配项:

a <- "I hate extra spaces elephant"
gsub("(?:\\G(?!^)|(?<!\\S)\\S5)\\K\\S", ".", a, perl = TRUE)

请参阅 R demo 和 regex demo。

详情

(?:\G(?!^)|(?&lt;!\S)\S5) - 上一个成功匹配的结束或五个非空白字符前面没有非空白字符 \K - match reset operator 丢弃目前匹配的文本 \S - 任何非空白字符。

【讨论】:

【参考方案2】:

gsubfngsub 类似,只是替换字符串可以是输入匹配并输出替换的函数。该函数可以选择性地表示为一个公式,就像我们在这里所做的那样,将每个单词字符串替换为替换该字符串的函数的输出。不需要复杂的正则表达式。

library(gsubfn)

gsubfn("\\w+", ~ paste0(substr(x, 1, 5), strrep(".", max(0, nchar(x) - 5))), a)
## [1] "I hate extra space. eleph..."

或几乎相同,只是功能略有不同:

gsubfn("\\w+", ~ paste0(substr(x, 1, 5), substring(gsub(".", ".", x), 6)), a)
## [1] "I hate extra space. eleph..."

【讨论】:

以上是关于量词可以用于R中的正则表达式替换吗?的主要内容,如果未能解决你的问题,请参考以下文章

可以在 Java 的正则表达式量词中传递引用吗?

bash 中的正则表达式量词——简单与扩展匹配 n 次

java正则表达式-量词

java正则表达式-量词

正则表达式匹配

正则表达式 丨JavaScript 高级