请问有人能准确解释一下这些gsub参数吗?

4

我有一段代码,是用来在找到下划线"_"后截取字符串的,但是我不理解传递给gsub函数的操作符/参数是如何使这种操作成为可能的。特别是为什么我需要使用gsub "\\1"而不是""。我注意到gsub空字符串的输出会将整个字符串删除。我还有一点困惑的是操作符的使用方式,尤其是括号和方括号:

AAA <- "ATGAS_1121"
(aa <- gsub("([^_]*).*", "\\1", AAA))
## [1] "ATGAS"

请注意,本文主要参考了以下来源:R remove part of string 谢谢,感激不尽。

1
"([^_]*).*" - rawr
2个回答

7

在正则表达式中,(..) 被称为捕获组,它可以捕获与组内模式匹配的所有字符。您可以通过反向引用组索引号来引用这些字符。

gsub("([^_]*).*", "\\1", AAA)

([^_]*)会捕获从开头开始但不包括_的所有字符,且可以出现零次或多次。接下来的.*将匹配剩余的所有字符。gsub将用替换部分中的字符替换所有匹配的字符。如果您的代码类似于:

gsub("([^_]*).*", "", AAA)

如果我们匹配了所有字符但是只捕获那些在起始位置出现(不是_符号)的字符,那么将会移除掉所有字符。所以通过用组索引1中存在的字符替换匹配的字符,将会得到_符号前面的部分。

你也可以使用\K来实现相同的结果。

> gsub("[^_]*\\K.*", "", AAA, perl = TRUE)
[1] "ATGAS"

\K 是一个 PCRE 特性,你需要启用 perl=TRUE 参数。其作用是保留已匹配的文本,并将其从整体正则表达式匹配结果中剔除。


或者您可以直接使用 gsub("_.*", "", AAA) - David Arenburg
我认为 sub 对于所有情况都足够了。 - Avinash Raj

2

为什么我需要使用gsub \\1而不是""

反向引用告诉引擎匹配由捕获组捕获的字符。通过将要分组的字符放在一对括号(...)中,可以创建一个捕获组。从左到右的每个一组捕获括号都被分配一个数字,无论引擎在评估匹配时是否使用这些括号。

在这种情况下,您需要在替换调用中使用反向引用\1,将由第1组匹配的字符赋值给新字符串aa。如果使用"",则会将空值赋给aa,因为正则表达式模式匹配整个字符串。

我也有点困惑运算符如何使用...括号

你所问的方括号 [ ... ] 被称为 字符类,它定义了一组字符。意思是“匹配类别中指定的一个字符”。

我建议这样做:

在这个例子中,根本不需要正则表达式,你可以简单地分割字符串。

AAA <- 'ATGAS_1121'
strsplit(AAA, '_', fixed=T)[[1]][1]
# [1] "ATGAS"

如果您坚持使用正则表达式,您可以使用以下方式的 sub

AAA <- 'ATGAS_1121'
sub('_.*', '', AAA)
# [1] "ATGAS"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接