如何用gsub正则提取字符串中数字间的目标字符?
解决方案
直接使用带有分支结构的正则表达式结合gsub(启用Perl兼容模式),即可覆盖所有场景,代码如下:
my_string <- c("12 aöc-ABC 3 a", "43XY/zz23ab", "acs", "23 as c", "f~ds22 d", "1 3") result <- gsub( "^\\d+\\s*(.*?)\\s*\\d+.*$|^\\d+\\s*(.*)$|^(.*?)\\s*\\d+$|^([^\\d]+)$|^\\d+(\\s+\\d+)*$", "\\1\\2\\3\\4", my_string, perl = TRUE ) # 将空字符串替换为NA result[result == ""] <- NA # 输出结果 result # [1] "aöc-ABC" "XY/zz" "acs" "as c" "f~ds" NA
正则分支说明
每个分支对应一种场景:
^\\d+\\s*(.*?)\\s*\\d+.*$:匹配存在前后两个数字的字符串,捕获两个数字之间的内容(自动去除首尾空格),忽略后续无关内容。^\\d+\\s*(.*)$:匹配仅开头有数字的字符串,捕获数字后空格之后的所有内容。^(.*?)\\s*\\d+$:匹配仅结尾有数字的字符串,捕获数字前空格之前的所有内容。^([^\\d]+)$:匹配完全不含数字的字符串,直接捕获整个字符串。^\\d+(\\s+\\d+)*$:匹配**仅含数字(含空格分隔的多个数字)**的字符串,无有效捕获内容,替换后得到空字符串,最后转为NA。
原正则失效原因
原正则^\\d*\\s*([^[:digit:]])+\\d*.*存在两个核心问题:
([^[:digit:]])+只会捕获最后一个非数字字符,因为+作用在字符组上,捕获组仅保留最后一次匹配的内容。- 未覆盖仅含前/后数字、无数字、仅含数字等场景,匹配逻辑不完整。
内容的提问来源于stack exchange,提问作者LulY
相关产品推荐
相关产品推荐

