如何用Base R正则匹配字母/数字后的最后三个下划线并拆分字符串
解决方案:用Base R正则高效拆分最后三个下划线前后内容
方法1:使用strsplit结合正向断言
直接利用Perl风格正则的正向否定先行断言定位最后一组三个下划线,拆分后直接得到目标两部分:
x <- c("three___thenfour____1", "only_three___k") # 拆分字符串 result <- strsplit(x, "(?<=.)___(?!.*___)", perl = TRUE) result # [[1]] # [1] "three___thenfour" "_1" # [[2]] # [1] "only_three" "k"
正则解释:
(?<=.):正向后顾断言,确保三个下划线前至少有一个字符(避免匹配字符串开头的无效情况)___:匹配目标三个下划线(?!.*___):正向否定先行断言,确保这三个下划线之后的内容中不再出现三个下划线,从而精准定位最后一组三个下划线
如果需要将结果整理成矩阵/数据框,可以用do.call(rbind, result)快速转换:
do.call(rbind, result) # [,1] [,2] # [1,] "three___thenfour" "_1" # [2,] "only_three" "k"
方法2:使用strcapture一次性提取前后内容
Base R的strcapture可以直接通过正则捕获组一次性提取前后两部分,返回结构化的数据框,效率更高:
pattern <- "^(.*?)___(?!.*___)(.*)$" strcapture(pattern, x, data.frame(pre = character(), post = character()), perl = TRUE) # pre post # 1 three___thenfour _1 # 2 only_three k
正则解释:
(.*?):非贪婪匹配,捕获三个下划线之前的所有内容(直到遇到最后一组三个下划线)___(?!.*___):匹配最后一组三个下划线(逻辑同方法1)(.*)$:捕获三个下划线之后的所有内容直到字符串结尾
原代码问题分析
你之前的sub正则^(.+)___(?:.(?!___))+$中,(.+)是贪婪匹配,会尽可能多的捕获字符,导致第一个字符串中把____1里的前一个下划线也包含进了捕获组,最终得到three___thenfour_。改用非贪婪匹配或先行断言限制最后一组下划线的位置,就能解决这个问题。
内容的提问来源于stack exchange,提问作者Benjamin
相关产品推荐
相关产品推荐

