匹配字符串末尾的某些数字

时间:2012-11-21 22:08:09

标签: regex r

我有一个字符串向量:

s <- c('abc1',   'abc2',   'abc3',   'abc11',   'abc12', 
       'abcde1', 'abcde2', 'abcde3', 'abcde11', 'abcde12', 
       'nonsense')

我希望正则表达式仅匹配以abc开头并以31112结尾的字符串。换句话说,正则表达式必须排除abc1但不排除abc11abc2但不排除abc12,依此类推。

我认为使用前瞻断言很容易做到这一点,但我找不到办法。有吗?


编辑:感谢下面的海报,指出原帖中的严重歧义。

实际上,我有很多字符串。它们都以数字结尾:一些在0中,一些在9中,一些在数字之间。我正在寻找一个匹配所有字符串的正则表达式,除了那些以字母后跟1或2结尾的字符串。(正则表达式也应该只匹配那些以abc开头的字符串,但这是一个简单的问题。)

我尝试使用负前瞻断言来创建这样的正则表达式。但我没有任何成功。


感谢所有回复和评论的人。受到你们几个人的启发,我最终使用了这个组合:grepl('^abc', s) & !grepl('[[:lower:]][12]$', s)

4 个答案:

答案 0 :(得分:3)

这是你想要的吗?

s[grepl("abc.*(3|11|12)", s)]
[1] "abc3"    "abc11"   "abc12"   "abcde3"  "abcde11" "abcde12"

排除的字符串是:

s[!grepl("abc.*(3|11|12)", s)]
[1] "abc1"     "abc2"     "abcde1"   "abcde2"   "nonsense"

编辑:正如评论所示,您的要求存在一些歧义。更全面的正则表达式将测试字符串开始^和字符串结束$,并且可能只允许字母字符[[:alpha:]]在最终数字之前:

s[grepl("^abc[[:alpha:]]*.*(3|11|12)$", s)]
[1] "abc3"    "abc11"   "abc12"   "abcde3"  "abcde11" "abcde12"

您还可以通过传递参数grepvalue=TRUE直接返回值,从而在代码中保存一些重复:

grep("^abc[[:alpha:]]*.*(3|11|12)$", s, value=TRUE)
[1] "abc3"    "abc11"   "abc12"   "abcde3"  "abcde11" "abcde12"

答案 1 :(得分:3)

在这种情况下,我认为使用两个简单的正则表达式更容易,而不是一个复杂的正则表达式:

s <- c('abc1',   'abc2',   'abc3',   'abc11',   'abc12', 
       'abcde1', 'abcde2', 'abcde3', 'abcde11', 'abcde12', 
       'nonsense')

s[grepl("^abc", s) & grepl("(3|11|12)$", s)]

答案 2 :(得分:1)

在这种情况下你也可以使用substring

z <- nchar(s)
s[substring(s, 1, 3) == "abc" & substring(s, z) == "3" | 
    substring(s, z-1) %in%  c("12", "11")] 

答案 3 :(得分:0)

专门查看所要求的数字,即可:

n <-  c(3,11,12)

s[sub('abc[^[:digit:]]*([[:digit:]]+)$',s, replacement='\\1') %in% n]
 [1] "abc3"    "abc11"   "abc12"   "abcde3"  "abcde11" "abcde12"

这不会混淆11 for 1:

 n <-  c(3,1,12)

s[sub('abc[^[:digit:]]*([[:digit:]]+)$',s, replacement='\\1') %in% n]
 [1] "abc1"    "abc3"    "abc12"   "abcde1"  "abcde3"  "abcde12"

对于您的编辑,不以1或2结尾(并使用两个正则表达式)

s[grepl('^abc',s) & !(sub('.*[^[:digit:]]([[:digit:]]+)$',s, replacement='\\1') %in% c(1,2))]
[1] "abc3"    "abc11"   "abc12"   "abcde3"  "abcde11" "abcde12"