R语言正则表达式匹配字符串模式及位置的问题排查
解决stringr中匹配"Web_797后接任意内容到Web_797"的正则问题
首先得指出你原来的正则模式问题所在:你写的"Web_797-*Web_797"完全不符合你的需求——正则里的*是用来修饰它前面的字符或分组的,这里它修饰的是-,意思是匹配零个或多个连字符,所以这个模式只能匹配像Web_797Web_797、Web_797-Web_797这类仅隔连字符或无间隔的情况,根本无法匹配中间夹了其他内容的Web_797-xxx-Web_797。
下面给你两种场景的解决方案,你可以根据自己的需求选择:
场景1:获取所有非重叠的"Web_797→Web_797"匹配
如果你想要的是从一个Web_797开始,到下一个最近的Web_797结束的匹配(不重叠),可以用非贪婪模式的正则:
library(stringr) String <- "Web_797-Web_797-Web_797-Web_797-PCP_IM_PAR-Pharm_1-Pharm_1- Web_797-PCP_IM_PAR-Prior_OP-Web_797-Prior_OP-Event_0-" # 正确的正则模式:Web_797 后接任意字符(非贪婪)直到 Web_797 pattern <- regex("Web_797.*?Web_797") # 获取所有匹配的位置 matches <- str_locate_all(String, pattern)[[1]] matches
运行后会得到这些结果:
start end [1,] 1 15 [2,] 17 31 [3,] 33 102 [4,] 104 138
这里每一行都是一个独立的、不重叠的匹配,比如第三行就是从第33位的Web_797到第102位的Web_797(中间夹了PCP_IM_PAR-Pharm_1-Pharm_1- )。
场景2:获取所有可能的重叠匹配(包括跨多个Web_797的情况)
如果你的需求是找出所有以Web_797开头,到任意后续Web_797结束的子串位置(比如从第一个Web_797到第三个、第四个Web_797这种跨多个的情况),直接用str_locate_all无法做到,因为它默认不支持重叠匹配。我们可以拆分步骤来实现:
library(stringr) String <- "Web_797-Web_797-Web_797-Web_797-PCP_IM_PAR-Pharm_1-Pharm_1- Web_797-PCP_IM_PAR-Prior_OP-Web_797-Prior_OP-Event_0-" # 第一步:获取所有Web_797的起始和结束位置 web_positions <- str_locate_all(String, "Web_797")[[1]] starts <- web_positions[, 1] ends <- web_positions[, 2] # 第二步:生成所有起始位置早于结束位置的组合 all_matches <- expand.grid(start = starts, end = ends) all_matches <- all_matches[all_matches$start < all_matches$end, ] # 查看结果 all_matches
这个代码会生成所有符合条件的位置对,比如:
- 第1位的
Web_797可以匹配到第15、31、45、102、138位的Web_797 - 第17位的
Web_797可以匹配到第31、45、102、138位的Web_797
以此类推,完全覆盖你想要的所有可能的组合。
内容的提问来源于stack exchange,提问作者Vaishak N Chandran
相关产品推荐
相关产品推荐

