Regex 替换R中列表中除特定正则表达式之外的所有内容

Regex 替换R中列表中除特定正则表达式之外的所有内容,regex,r,Regex,R,我想替换列表中与给定模式不匹配的所有内容。我使用的是R版本3.1.3(2015-03-09)-“平滑人行道” 我列举的例子如下: y <- c("D CCNA_01234 This is example 1 bis", "D CCNA_02345 This is example 2", "D CCNA_12345 This is example 3", "D CCNA_23468 This is example 4") 到目前为止,我已通过以下方式删除了比赛的前一部分: y_begin_

我想替换列表中与给定模式不匹配的所有内容。我使用的是R版本3.1.3(2015-03-09)-“平滑人行道”

我列举的例子如下:

y <- c("D CCNA_01234 This is example 1 bis", "D CCNA_02345 This is example 2", "D CCNA_12345 This is example 3", "D CCNA_23468 This is example 4")
到目前为止,我已通过以下方式删除了比赛的前一部分:

y_begin_rm <- sub("D ", "", y)
问题似乎在于匹配中指定的数字完全是通过字符串查看的,而不是我想要的精确组合。因此,短语“这是示例”后面的数字带来了很多麻烦。当我省略数字或仅在CCNA_字符串后面放置一个数字时,它工作正常:

y_CCNA <- sub("[^CCNA_]*$", "", y_begin_rm)

有没有办法指定我要查找的确切模式(CCNA_u0[0-9][0-9][0-9][0-9][0-9])?另外,是否有一种可能的方法可以在单个步骤中完成(在单个正则表达式中删除匹配之前和之后)


提前谢谢

使用基R,您可以直接从原始向量
y

sub(".*(CCNA_\\d+).*", "\\1", y)
## [1] "CCNA_01234" "CCNA_02345" "CCNA_12345" "CCNA_23468"
另一个选项是使用
stringi

library(stringi)
stri_extract_first_regex(y, "CCNA_\\d+")
## [1] "CCNA_01234" "CCNA_02345" "CCNA_12345" "CCNA_23468"
如果每个字符串中有超过1个
CCNA
模式,请改用
stri\u extract\u all\u regex

如果您想在
CCNA\uu
之后精确匹配5位数字,您也可以这样做

stri_extract_first_regex(y, "CCNA_\\d{5}")
## [1] "CCNA_01234" "CCNA_02345" "CCNA_12345" "CCNA_23468"
当然,
stringr

library(stringr)
str_extract(y, "CCNA_\\d{5}")
## [1] "CCNA_01234" "CCNA_02345" "CCNA_12345" "CCNA_23468"

这里有一种方法,使用我维护的包qdapRegex(我更喜欢this或stringi/stringr)作为基础,以实现一致性和易用性。我还展示了一种基本方法。在任何情况下,我都会将其视为一个“提取”问题,而不是一个“sub-everything but”subbing问题

y <- c("D CCNA_01234 This is example 1 bis", "D CCNA_02345 This is example 2", 
    "D CCNA_12345 This is example 3", "D CCNA_23468 This is example 4")

library(qdapRegex)
unlist(rm_default(y, pattern = "CCNA_\\d{5}", extract = TRUE))

## [1] "CCNA_01234" "CCNA_02345" "CCNA_12345" "CCNA_23468"
以下是一些方法:

1)捆扎带。这使用了一个特别简单的模式。它利用gsubfn包中的
Straplyc

library(gsubfn)
strapplyc(y, "CCNA_\\d{5}", simplify = TRUE)
## [1] "CCNA_01234" "CCNA_02345" "CCNA_12345" "CCNA_23468"
下面是正则表达式的可视化:

CCNA_\d{5}

1a)如果CCNA的出现次数仅在5位数之前,那么我们可以简化前面的解决方案,如下所示:

strapplyc(y, "CCNA_.{5}", simplify = TRUE)
## [1] "CCNA_01234" "CCNA_02345" "CCNA_12345" "CCNA_23468"
2)sub。这里的模式稍微复杂一些,但是使用
sub
我们可以在没有任何附加包的情况下完成:

sub(".*(CCNA_\\d{5}).*", "\\1", y)
## [1] "CCNA_01234" "CCNA_02345" "CCNA_12345" "CCNA_23468"
sapply(strsplit(y, " "), "[", 2)
## [1] "CCNA_01234" "CCNA_02345" "CCNA_12345" "CCNA_23468"
substr(y, 3, 12)
## [1] "CCNA_01234" "CCNA_02345" "CCNA_12345" "CCNA_23468"
3)strsplit如果所需的部分始终是第二个“单词”(问题中就是这种情况),那么这将起作用,并且同样不需要包:

sub(".*(CCNA_\\d{5}).*", "\\1", y)
## [1] "CCNA_01234" "CCNA_02345" "CCNA_12345" "CCNA_23468"
sapply(strsplit(y, " "), "[", 2)
## [1] "CCNA_01234" "CCNA_02345" "CCNA_12345" "CCNA_23468"
substr(y, 3, 12)
## [1] "CCNA_01234" "CCNA_02345" "CCNA_12345" "CCNA_23468"
4)substr如果所需部分始终是问题中的字符3到12,那么我们可以再次使用
substr
substring
,而不使用任何包:

sub(".*(CCNA_\\d{5}).*", "\\1", y)
## [1] "CCNA_01234" "CCNA_02345" "CCNA_12345" "CCNA_23468"
sapply(strsplit(y, " "), "[", 2)
## [1] "CCNA_01234" "CCNA_02345" "CCNA_12345" "CCNA_23468"
substr(y, 3, 12)
## [1] "CCNA_01234" "CCNA_02345" "CCNA_12345" "CCNA_23468"

我猜你指的是stringR/stringi?:)regmatches(y,regexpr('CCNA\\d{5}',y))@ShenglinChen你有什么想说的吗?我想他们说你可以使用
regexpr
而不是
gregexpr
substr(y, 3, 12)
## [1] "CCNA_01234" "CCNA_02345" "CCNA_12345" "CCNA_23468"