【问题标题】:How to iteratively match word sequences如何迭代匹配单词序列
【发布时间】:2020-07-08 11:42:40
【问题描述】:

我有这样的字符串:

test <- c("oh i mean well i do n't know well he 's like oh",
          "yeah so well he did n't say oh he said f** well you know what he 's like",
          "oh you know well why well maybe he thought oh well good", 
          "oh my god well what the hell did he oh you know")

我想匹配以oh 开头并以well 结尾的所有单词序列,反之亦然,以well 开头并以oh 结尾。 str_extract_all 的这种使用确实匹配了一些目标序列,但不是全部,因为它无法迭代匹配,也就是说,它不会从每个ohwell 重新开始一次它在比赛中消耗了它:

library(stringr)
strings <- unlist(str_extract_all(test, "\\boh\\b.*?\\bwell\\b|\\bwell\\b.*?\\boh\\b"))
[1] "oh i mean well"           "well he 's like oh"       "well he did n't say oh"   "oh you know well"        
[5] "well maybe he thought oh" "oh my god well" 

完整的输出是这样的:

[1] "oh i mean well"     "well he 's like oh"     "well he did n't say oh"     "oh he said f** well" 
[5] "oh you know well"  "oh well"   "well maybe he thought oh"     "oh my god well"
[9] "well what the hell did he oh" 

【问题讨论】:

  • 怎么样:c(unlist(str_extract_all(test, "\\boh\\b.*?\\bwell\\b")), unlist(str_extract_all(test, "\\bwell\\b.*?\\boh\\b")))
  • 你能把它分成两个正则表达式吗?...即c(unlist(str_extract_all(test, "\\boh\\b.*?\\bwell\\b")), unlist(str_extract_all(test, "\\bwell\\b.*?\\boh\\b")))
  • 改用非消耗性环视集群。对于交替的第一方面,它将是 (?&lt;=\\boh\\b).*?(?=\\bwell\\b)
  • 我会让@GKi按照他一分钟前发布的那样做:)
  • @Sotos 太好了!

标签: r regex stringr


【解决方案1】:

您可以使用您的正则表达式使用str_extract_all 一个oh...well 和一个well...oh

library(stringr)
unlist(c(str_extract_all(test, "\\boh\\b.*?\\bwell\\b")
       , str_extract_all(test, "\\bwell\\b.*?\\boh\\b")))
#[1] "oh i mean well"                       
#[2] "oh he said f** well"                  
#[3] "oh you know well"                     
#[4] "oh well"                              
#[5] "oh my god well"                       
#[6] "well i do n't know well he 's like oh"
#[7] "well he did n't say oh"               
#[8] "well why well maybe he thought oh"    
#[9] "well what the hell did he oh"         

或者如果是最短序列:

unlist(c(str_extract_all(test, "\\boh\\b((?!\\boh\\b).)*?\\bwell\\b")
 , str_extract_all(test, "\\bwell\\b((?!\\bwell\\b).)*?\\boh\\b")))
#[1] "oh i mean well"               "oh he said f** well"         
#[3] "oh you know well"             "oh well"                     
#[5] "oh my god well"               "well he 's like oh"          
#[7] "well he did n't say oh"       "well maybe he thought oh"    
#[9] "well what the hell did he oh"

数据:

test <- c("oh i mean well i do n't know well he 's like oh",
          "yeah so well he did n't say oh he said f** well you know what he 's like",
          "oh you know well why well maybe he thought oh well good", 
          "oh my god well what the hell did he oh you know")

【讨论】:

  • 感谢您的解决方案。我从来没有如此纠结于接受哪个答案,但最终决定接受@Wiktor 的答案,因为它提供了对正则表达式的更多见解。
【解决方案2】:

您可以使用stringr::str_match_all 解决方案(因为stringr::str_extract_all“丢失”所有捕获的子字符串):

test <- c("oh i mean well i do n't know well he 's like oh",
"yeah so well he did n't say oh he said f** well you know what he 's like", 
"oh you know well why well maybe he thought oh well good",
"oh my god well what the hell did he oh you know")
res <- stringr::str_match_all(test, "(?=(\\boh\\b(?:(?!\\boh\\b).)*?\\bwell\\b|\\bwell\\b(?:(?!\\bwell\\b).)*?\\boh\\b))")

unlist(lapply(res, function(x) x[,-1]))

查看R demo onlineregex demo

详情

  • (?= - 积极前瞻的开始:
    • ( - 捕获组的开始:
      • \boh\b(?:(?!\boh\b).)*?\bwell\b - oh 整个单词,然后是任何 0+ 字符,尽可能少的不以整个单词开头的字符 oh 直到最左边 well 整个单词
      • | - 或
      • \bwell\b(?:(?!\bwell\b).)*?\boh\b - well 整个单词,然后是任何 0+ 字符,尽可能少的不以整个单词开头的字符 well 直到最左边 oh 整个单词
    • ) - 捕获组结束
  • ) - 正向预测结束。

输出:

[1] "oh i mean well"               "well he 's like oh"          
[3] "well he did n't say oh"       "oh he said f** well"         
[5] "oh you know well"             "well maybe he thought oh"    
[7] "oh well"                      "oh my god well"              
[9] "well what the hell did he oh"

【讨论】:

  • 太棒了!非常感谢。如果你不介意,一个问题:我永远不知道(?: 是什么意思——它是什么?
  • @ChrisRuehlemann (?:...) 是一个 non-capturing group,用于对一系列模式进行分组(使用替代方案或量化它),而不会将捕获的文本存储在单独的内存中插槽。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-10-29
  • 2020-05-24
  • 1970-01-01
  • 1970-01-01
  • 2018-10-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多