考虑以下向量x
x <- c("000a000b000c", "abcd00ab", "abcdefg", "000s00r00g00t00")
使用单个正则表达式,我只想保留x
包含三个以上字母的元素。以下是规则:
x
的字符串元素可以是任意数量的字符我想到的简单方法是删除所有不是字母的内容,然后取出字符数,如下所示。
x[nchar(gsub("[0-9]+", "", x)) > 3]
# [1] "abcd00ab" "abcdefg" "000s00r00g00t00"
我知道像[a-z]{4,}
这样的陈述可以找到四个或更多连续的小写字母。但是,如果单个字母分散在字符串上呢?如何保持字母的“运行计数”,以便当它超过3时,它变成不匹配?现在我所能想到的就是多次写[a-z]+
,但如果我想匹配五个或更多字母,这会变得很难看。
这让我在那里,但你可以看到这对于更长的字符串来说这可能是多么丑陋。
grep("[a-z]+.*[a-z]+.*[a-z]+.*[a-z]+.*", x)
# [1] 2 3 4
有没有办法用更好的正则表达式做到这一点?
答案 0 :(得分:5)
您可以使用重复运算符:{n}
匹配上一个标记或组n
次。为了提高匹配效率,您还应具体说明字母之间可能匹配的内容(在您的情况下只有数字,而不是&#34;任何&#34;字符(点.
匹配)):
^(?:[0-9]*[a-z]){4}[0-9a-z]*$
匹配包含至少3个小写字母的所有字符串。
<强>解释强>
^ # Start of string
(?: # Start of a (non-capturing) group:
[0-9]* # Match any number of digits
[a-z] # Match one lowercase ASCII letter
){4} # Repeat the group exactly four times
[0-9a-z]* # Then match any following digits/letters
$ # until the end of the string
在R:
grep("^(?:[0-9]*[a-z]){4}[0-9a-z]*$", x, perl=TRUE, value=TRUE);
为您提供一个字符向量,其中包含与正则表达式匹配的所有元素。
答案 1 :(得分:5)
在\\D
与非数字匹配的情况下尝试此操作,.*
匹配0个或更多字符的字符串,(...){4}
表示匹配4次,即超过3个。
grep("(\\D.*){4}", x, value = TRUE)
如果有4个或更多的非数字,这将匹配。如果需要超过5,只需将4替换为6.如果在regexp中使用数字3很重要,那么请尝试使用此模式(\\D.*){3}\\D
。
答案 2 :(得分:3)
下面的grep命令会找到包含四个或更多字母的元素
> grep("^(?:[^a-z]*[a-z]){4}", x, perl=T, value=T)
[1] "abcd00ab" "abcdefg" "000s00r00g00t00"
OR
> grep("^(?:[^a-z]*[a-z]){3}[^a-z]*[a-z]", x, perl=T, value=T)
[1] "abcd00ab" "abcdefg" "000s00r00g00t00"
要查找包含5个或更多字母的元素,
> grep("^(?:[^a-z]*[a-z]){5}", x, perl=T, value=T)
[1] "abcd00ab" "abcdefg"
<强>解释强>
^ the beginning of the string
(?: group, but do not capture (4 times):
[^a-z]* any character except: 'a' to 'z' (0 or
more times)
[a-z] any character of: 'a' to 'z'
){4} end of grouping