量词可以用于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 = TRUE
或perl = 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<-
替换它。所以这可能是实现目标的好方法。但如果您的问题是“现有的正则表达式函数是否有能力”,答案是否定的。
您发布的是 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(?!^)|(?<!\S)\S5)
- 上一个成功匹配的结束或五个非空白字符前面没有非空白字符
\K
- match reset operator 丢弃目前匹配的文本
\S
- 任何非空白字符。
【讨论】:
【参考方案2】:gsubfn
与gsub
类似,只是替换字符串可以是输入匹配并输出替换的函数。该函数可以选择性地表示为一个公式,就像我们在这里所做的那样,将每个单词字符串替换为替换该字符串的函数的输出。不需要复杂的正则表达式。
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中的正则表达式替换吗?的主要内容,如果未能解决你的问题,请参考以下文章