4

我有一个字符串向量:

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

我想要一个正则表达式只匹配以、或开头abc和结尾的字符串。换句话说,正则表达式必须排除但不是,但不是,等等。31112abc1abc11abc2abc12

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


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

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

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


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

4

4 回答 4

4

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

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

s[grepl("^abc", s) & grepl("(3|11|12)$", s)]
于 2012-11-21T22:34:13.050 回答
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"

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

grep("^abc[[:alpha:]]*.*(3|11|12)$", s, value=TRUE)
[1] "abc3"    "abc11"   "abc12"   "abcde3"  "abcde11" "abcde12"
于 2012-11-21T22:14:00.523 回答
1

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

z <- nchar(s)
s[substring(s, 1, 3) == "abc" & substring(s, z) == "3" | 
    substring(s, z-1) %in%  c("12", "11")] 
于 2012-11-21T22:18:38.293 回答
0

专门寻找请求的数字给出了这个:

n <-  c(3,11,12)

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

这不会将 11 与 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"
于 2012-11-21T22:39:15.740 回答