使用正则表达式选择性地提取R中的子字符串



假设我有以下字符串:

string <- c(
"DATE_OF_BIRTH_B1",
"HEIGHT_BABY2",
"WEIGHT_BABY_3",
"OTHER_CONDITION_4",
"OTHER_OPERATION_5"
)

如何在gsub()中使用正则表达式提取:

  • 除了尾部下划线之外的所有内容,直到前三个字符串中的数字后缀
  • 最后两个字符串中没有任何内容

换句话说,我预期的gsub()输出是:

"DATE_OF_BIRTH_B", "HEIGHT_BABY", "WEIGHT_BABY"

我设法使用gsub("(.+_B[A-Z]*)_?[0-9]", "\1", string)从前三个字符串中提取所需的子字符串,但未能排除最后两个字符串。

有人能帮我纠正和改进我的正则表达式吗?非常感谢!

删除OTHER或后缀。

gsub("^OTHER.*|_?[0-9]+$", "", string)
#> [1] "DATE_OF_BIRTH_B"
#> [2] "HEIGHT_BABY"    
#> [3] "WEIGHT_BABY"    
#> [4] ""               
#> [5] ""  

或者,如果您特别想要捕获组,请使用非贪婪捕获。

gsub("(OTHER.*)?(.*?)_?[0-9]", "\2", string)
#> [1] "DATE_OF_BIRTH_B"
#> [2] "HEIGHT_BABY"    
#> [3] "WEIGHT_BABY"    
#> [4] ""               
#> [5] "" 

如果您期望gsub(或sub,通常在这种情况下,您真的应该使用sub,因为您只期望一个替换操作(返回替换结果或空字符串,则需要遵循以下技术:

sub("...(<what_you_want_to_extract>)...|.+", "\1", x)

也就是说,您的正则表达式位于|交替运算符之前,后面跟着与尽可能多的一个或多个字符匹配的.+

因此,在您的情况下,假设您的regex正是您所需要的并且满足您的所有要求,则可以使用

> res <- sub("(.+_B[A-Z]*)_?[0-9]|.+", "\1", string)
> res
[1] "DATE_OF_BIRTH_B" "HEIGHT_BABY"     "WEIGHT_BABY"     ""                ""      

如果你需要删除空项目,只需使用

> res[nzchar(res)]
[1] "DATE_OF_BIRTH_B" "HEIGHT_BABY"     "WEIGHT_BABY"

最新更新