繁体   English   中英

以任意顺序提取2个单词

[英]Extract 2 words in any order

我想以任何顺序提取猫和狗

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)).*

参见regex演示

细节

  • .* -除换行符以外的任何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替换模式将Group 1和Group 2的值插入到结果字符串中(这样,结果就是dogcat ,一个空格以及catdog )。

也可以在线观看R演示

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以应用自定义替换逻辑:

> 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"

这里,

  • ^ -字符串锚点的开始
  • (?:.*((dog).*(cat)|(cat).*(dog)).*|.*) -与两个选项之一匹配的非捕获组.*((dog).*(cat)|(cat).*(dog)).*
    • .* -尽可能多的0个字符
    • ((dog).*(cat)|(cat).*(dog)) -与两个选项之一匹配的捕获组
      • (dog).*(cat) - dog (第2组,分配给a变量),任何0+字符尽可能多,然后cat (第3组,分配给b变量)
      • |
      • (cat).*(dog) dog (第4组,分配给y变量),尽可能多的0个字符,然后cat (第5组,分配给z变量)
    • .* -尽可能多的0个字符
      • | - 要么
      • .* -任何0+个字符
  • $ -字符串锚点的结尾。

匿名函数中的x表示此处的“技术”组1值,我们用nchar检查组1的匹配长度是否不为零,如果不为空,则用自定义逻辑替换,如果组1为空,我们用NA代替。

我们可以使用str_extract_all包捕获组。

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"

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM