有人可以解释这个通配符 gsub 代码,尤其是“\\1”部分

Can someone explain this wildcard gsub code, particularly the "\\1" part

如果我有以下特征向量:

names(x)
[1] "EMM88 emm88.0 (emm-cluster E4)"   "EMM225 emm225.0 (emm-cluster D4)"
[3] "EMM52 emm52.0 (emm-cluster D4)"   "EMM2 emm2.0 (emm-cluster E4)"    
[5] "EMM114 emm114.0 (emm-cluster E4)"

我只想保留 "EMM?" 部分,包括数字(例如 "EMM88" 在 "EMM88 emm88.0 (emm-cluster E4)" 的情况下),我可以使用以下代码:

names(x) <- gsub("(.*?) .*", "\1", names(x))

并给出所需的输出:

names(x)
[1] "EMM88"  "EMM225" "EMM52"  "EMM2"   "EMM114"

我已阅读 "gsub" 的文档和一些其他问题,但仍在努力理解代码如何导致预期结果。

我理解第一个参数 ("(.*?) .*", "\1") 是要在第二个参数 (names(x)) 中寻找的模式。

我不明白 (.*?),

.* 表示任意数量的字符,那么将它们组合成 (.*?) .* 是什么意思?

添加 "\1" 有什么作用?

如您所见,我缺少一些 "wildcard" 和 "gsub" 编码知识的基础知识,非常感谢您的帮助。

.*? 尝试在字符串中的每个字符处停止,但正则表达式引擎想要报告整体匹配并且还需要匹配第一个捕获组之后的空格,因此它尝试在每个字符,直到它最终到达第一个空白。到目前为止的所有字符都存储在第一个捕获组中 - 在替换部分中称为 \1
表达式的其余部分消耗字符串的其余部分,并且字符串仅替换为第一个捕获组。

一般来说,点星是"expensive"(引擎试图在每个字符处停止),应该尽可能避免。


也就是说,您可以使用更有效的

names(x) <- gsub("([^ ]+).*", "\1", names(x))

相反。这会捕获第一组中不是空格的任何内容,并且可能会更快结束。