我想以任何顺序提取猫和狗
string1 <- "aasdfadsf cat asdfadsf dog"
string2 <- "asfdadsfads dog asdfasdfadsf cat"
我现在拥有的是猫和狗,还有中间的文本
stringr::str_extract(string1, "cat.*dog|dog.*cat"
我希望输出
cat dog
和
dog cat
对于string1和string2,分别
您可以将sub
与以下PCRE正则表达式一起使用:
.*(?|(dog).*(cat)|(cat).*(dog)).*
细节
.*
- 除了换行符之外的任何0+字符(匹配所有字符在模式开始时添加(?s)
)(?|(dog).*(cat)|(cat).*(dog))
- 分支重置组(?|...|...)
匹配两种选择中的任何一种:
(dog).*(cat)
- 第1组捕获dog
,然后捕获尽可能多的0+字符,第2组捕获cat
|
- 或
(cat).*(dog)
- 第1组捕获cat
,然后捕获尽可能多的0+字符,第2组捕获dog
(在分支重置组中,组ID重置为组+ 1之前的值).*
- 除了换行符之外的任何0+字符\1 \2
替换模式将第1组和第2组值插入到结果字符串中(因此结果只是dog
或cat
,一个空格,以及cat
或dog
)。
x <- c("aasdfadsf cat asdfadsf dog", "asfdadsfads dog asdfasdfadsf cat")
sub(".*(?|(dog).*(cat)|(cat).*(dog)).*", "\\1 \\2", x, perl=TRUE)
## => [1] "cat dog" "dog cat"
要在不匹配的情况下返回NA
,请使用正则表达式匹配特定模式或整个字符串,并将其与gsubfn
一起使用以应用自定义替换逻辑:
> gsubfn("^(?:.*((dog).*(giraffe)|(giraffe).*(dog)).*|.*)$", function(x,a,b,y,z,i) ifelse(nchar(x)>0, paste0(a,y," ",b,z), NA), x)
[1] "NA" "NA"
> gsubfn("^(?:.*((dog).*(cat)|(cat).*(dog)).*|.*)$", function(x,a,b,y,z,i) ifelse(nchar(x)>0, paste0(a,y," ",b,z), NA), x)
[1] "cat dog" "dog cat"
这里,
^
- 字符串anchor的开头(?:.*((dog).*(cat)|(cat).*(dog)).*|.*)
- 与两种选择中的任何一种相匹配的non-capturing group:.*((dog).*(cat)|(cat).*(dog)).*
:
.*
- 尽可能多的0个字符
((dog).*(cat)|(cat).*(dog))
- 与两种选择中的任何一种相匹配的capturing group:
(dog).*(cat)
- dog
(第2组,分配给a
变量),尽可能多的0+字符,然后cat
(第3组,分配给b
变量)
|
(cat).*(dog)
- dog
(第4组,分配给y
变量),尽可能多的0+字符,然后cat
(第5组,分配给z
变量)
.*
- 尽可能多的0个字符
|
- 或
.*
- 任何0+字符$
- 字符串anchor的结尾。匿名函数中的x
表示此处为“技术”的第1组值,我们使用nchar
检查第1组匹配长度是否为零,如果它不为空,则使用自定义逻辑替换,如果是第1组是空的,我们用NA
替换。
我们可以使用str_extract_all
包中的stringr和捕获组。
string1 <- "aasdfadsf cat asdfadsf dog"
string2 <- "asfdadsfads dog asdfasdfadsf cat"
string3 <- "asfdadsfads asfdadsfadf"
library(stringr)
str_extract_all(c(string1, string2, string3), pattern = "(dog)|(cat)")
# [[1]]
# [1] "cat" "dog"
#
# [[2]]
# [1] "dog" "cat"
#
# [[3]]
# character(0)
我们也可以设置simplify = TRUE
。输出将是一个矩阵。
str_extract_all(c(string1, string2, string3), pattern = "(dog)|(cat)", simplify = TRUE)
# [,1] [,2]
# [1,] "cat" "dog"
# [2,] "dog" "cat"
# [3,] "" ""
要么,
> regmatches(string1,gregexpr("cat|dog",string1))
[[1]]
[1] "cat" "dog"
> regmatches(string2,gregexpr("cat|dog",string2))
[[1]]
[1] "dog" "cat"