使用gsub或sub函数只获取字符串的一部分?

6
      Col
WBU-ARGU*06:03:04
WBU-ARDU*08:01:01
WBU-ARFU*11:03:05
WBU-ARFU*03:456

我有一列变量,其中有75行,类似于上面的列。我不太确定如何使用gsub或sub来获取第一个冒号后的整数。

期望输出:

      Col
WBU-ARGU*06:03
WBU-ARDU*08:01
WBU-ARFU*11:03
WBU-ARFU*03:456

我尝试了这个方法,但它似乎不起作用:
gsub("*..:","", df$col)

col 还是 Col - s_baldur
3个回答

4
以下内容也可能对你有所帮助。
sub("([^:]*):([^:]*).*","\\1:\\2",df$dat)

输出结果如下。
> sub("([^:]*):([^:]*).*","\\1:\\2",df$dat)
[1] "WBU-ARGU*06:03"   "WBU-ARDU*08:01"   "WBU-ARFU*11:03"   "WBU-ARFU*03:456b"

输入数据框的格式如下。

dat <- c("WBU-ARGU*06:03:04","WBU-ARDU*08:01:01","WBU-ARFU*11:03:05","WBU-ARFU*03:456b")
df <- data.frame(dat)

解释:以下仅供解释。

sub("      ##using sub for global subtitution function of R here.
([^:]*)     ##By mentioning () we are keeping the matched values from vector's element into 1st place of memory(which we could use later), which is till next colon comes it will match everything.
:           ##Mentioning letter colon(:) here.
([^:]*)     ##By mentioning () making 2nd place in memory for matched values in vector's values which is till next colon comes it will match everything.
.*"         ##Mentioning .* to match everything else now after 2nd colon comes in value.
,"\\1:\\2"  ##Now mentioning the values of memory holds with whom we want to substitute the element values \\1 means 1st memory place \\2 is second memory place's value.
,df$dat)    ##Mentioning df$dat dataframe's dat value.

这个代码可以运行,但是它没有包含“:”符号。对于第一个输入 WBU-ARGU06:03:04,输出结果为 WBU-ARGU0603。我该如何让它输出 WBU-ARGU*06:03? - nathan
@Nathan,但是当我检查时,我发现它只能正常工作> gsub("([^:]*):([^:]*).*","\\1:\\2",df$dat) [1] "WBU-ARGU*06:03" "WBU-ARDU*08:01" "WBU-ARFU*11:03" "WBU-ARFU*03:456b" - RavinderSingh13
1
我在“\1:\2”中漏掉了冒号,现在已经可以正常工作了,谢谢! - nathan
1
你不需要使用 gsub,只需要使用 sub 就足够了,因为你只需要在每个字符向量中匹配和替换一次。 - Wiktor Stribiżew

3

您可以使用

df$col <- sub("(\\d:\\d+):\\d+$", "\\1", df$col)

请查看正则表达式演示

详情

  • (\\d:\\d+) - 捕获组1(可以通过替换模式中的\1访问其值):一个数字,一个冒号和1个或多个数字。
  • : - 一个冒号
  • \\d+ - 1个或多个数字
  • $ - 字符串结尾。

R演示

col <- c("WBU-ARGU*06:03:04","WBU-ARDU*08:01:01","WBU-ARFU*11:03:05","WBU-ARFU*03:456")
sub("(\\d:\\d+):\\d+$", "\\1", col)
## => [1] "WBU-ARGU*06:03"  "WBU-ARDU*08:01"  "WBU-ARFU*11:03"  "WBU-ARFU*03:456"

另一种方法:

df$col <- sub("^(.*?:\\d+).*", "\\1", df$col)

请查看正则表达式演示

在此,

  • ^ - 字符串开头
  • (.*?:\\d+) - 第1组:0个或多个任意字符,尽可能少地匹配(由于使用了懒惰的*?量词),然后是:和1个或多个数字
  • .* - 剩下的字符串。

但是,它应该与PCRE正则表达式引擎一起使用,传递perl=TRUE

col <- c("WBU-ARGU*06:03:04","WBU-ARDU*08:01:01","WBU-ARFU*11:03:05","WBU-ARFU*03:456")
sub("^(.*?:\\d+).*", "\\1", col, perl=TRUE)
## => [1] "WBU-ARGU*06:03"  "WBU-ARDU*08:01"  "WBU-ARFU*11:03"  "WBU-ARFU*03:456"

查看R在线演示


谢谢您的演示,那真的很有帮助! - nathan
@nathan 我添加了另一种解决方案,基本上遵循你的逻辑:从开头获取子字符串直到第一个带有1个或多个数字的 :,然后删除其余部分。 - Wiktor Stribiżew

1
sub("(\\d+:\\d+):\\d+$", "\\1", df$Col)
[1] "WBU-ARGU*06:03"  "WBU-ARDU*08:01"  "WBU-ARFU*11:03"  "WBU-ARFU*03:456"

另外,您可以使用 stringi 来匹配您想要的内容(而不是替换掉您不想要的内容):

stringi::stri_extract_first(df$Col, regex = "[A-Z-\\*]+\\d+:\\d+")

略微更简洁的 stringr:
stringr::str_extract(df$Col, "[A-Z-\\*]+\\d+:\\d+")
# or
stringr::str_extract(df$Col, "[\\w-*]+\\d+:\\d+")

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