如何用PCRE正则匹配所有未被cat前置的dog?
正则表达式匹配未被
cat前置的dog(R语言PCRE) 需求说明
需要匹配所有未被cat前置的dog1/dog2/dog3,具体规则示例:
jump dog1 cat- 匹配dog1jump cat run dog1- 不匹配dog1(被cat前置)jump dog1 dog2- 匹配dog1和dog2jump dog1 dog2 cat run dog3- 匹配dog1、dog2,不匹配dog3(被cat前置)
尝试过的正则(未成功)
(?>^.*?\K(?:cat|(dog(1|2|3))))(?(1)|$.^)- 问题:无法匹配多个符合条件的
dog(比如jump dog1 dog2只能匹配一个)
- 问题:无法匹配多个符合条件的
(?>^.*?\K(?:cat|(\bdog(1|2|3))))- 问题:通过组1获取结果时未达到预期
解决方案(R语言PCRE)
方案1:分段提取匹配
先提取cat出现之前的所有文本,再在这段文本里匹配目标dog:
library(stringr) texts <- c( "jump dog1 cat", "jump cat run dog1", "jump dog1 dog2", "jump dog1 dog2 cat run dog3" ) result <- lapply(texts, function(x) { # 提取cat之前的内容(如果没有cat就取全部文本) prefix <- str_extract(x, "^.*?(?=\\s+cat|$)") # 匹配所有符合格式的dog str_extract_all(prefix, "\\bdog(1|2|3)\\b")[[1]] }) print(result)
输出结果:
[[1]] [1] "dog1" [[2]] character(0) [[3]] [1] "dog1" "dog2" [[4]] [1] "dog1" "dog2"
方案2:纯正则全局匹配
利用PCRE的(*SKIP)(*FAIL)机制,直接跳过cat及之后的所有内容,只保留前面的目标dog:
library(stringr) pattern <- "\\bcat\\b.*(*SKIP)(*FAIL)|\\bdog(1|2|3)\\b" result <- str_extract_all(texts, pattern) print(result)
正则逻辑:
\\bcat\\b.*(*SKIP)(*FAIL):匹配cat及之后的所有内容,标记为匹配失败并跳过这部分\\bdog(1|2|3)\\b:仅匹配不在cat之后的目标dog
输出结果与方案1完全一致,符合需求。
内容的提问来源于stack exchange,提问作者Fabio Correa
相关产品推荐
相关产品推荐

