我的目标是用一个符号替换字符串,重复与字符串一样多的字符,就像可以用\U\1
替换字母到大写字母一样,如果我的模式是"...(*)..."
我替换(*)
捕获的内容将是类似于x\q1
或{\q1}x
,所以我会得到如此多的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,}
但我不确定这是否真的是我感兴趣的事实。
编辑更新:
由于评论者提出,我用这个有趣的问题提供的具体示例更新了我的问题。我稍微修改了一下示例。假设我们有a <- "I hate extra spaces elephant"
,所以我们有兴趣在单词之间保持一个唯一的空格,每个单词的前 5 个字符(直到这里作为原始问题),但然后每个字符都有一个点(不确定这是否是原始问题中预期的,但没关系),所以生成的字符串将被"I hate extra space. eleph..."
(一个.
用于spaces
中的最后一个s
和 3ant
elephant
末尾的 3 个字母的点)。所以我首先保留前 5 个字符
gsub("(?<!\S)(\S{5})\S*", "\1", a, perl = TRUE)
[1] "I hate extra space eleph"
我应该如何用点或任何其他符号替换\S*
中的确切字符数?
量词不能用于替换模式,也不能使用它们匹配的字符数的信息。
您需要的是一个G
的基本 PCRE 模式,以查找字符串中特定位置之后的连续匹配项:
a <- "I hate extra spaces elephant"
gsub("(?:\G(?!^)|(?<!\S)\S{5})\K\S", ".", a, perl = TRUE)
请参阅 R 演示和正则表达式演示。
详
(?:G(?!^)|(?<!S)S{5})
- 上一个成功匹配的结束或五个非空格字符前面没有非空格字符K
- 匹配重置运算符丢弃到目前为止匹配的文本S
- 任何非空格字符。
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..."