我需要找一个正则表达式,它允许我找到我拥有所有必需数字但只有一次的字符串。
例如:
a <- c("12","13","112","123","113","1123","23","212","223","213","2123","312","323","313","3123","1223","1213","12123","2313","23123","13123")
我想得到:
"123" "213" "312"
模式123仅一次且以任何顺序和字符串的任何位置
我尝试了很多东西,这似乎更接近,但距离我想要的还很远:
grep('[1:3][1:3][1:3]', a, value=TRUE)
[1] "113" "313" "2313" "13123"
答案 0 :(得分:9)
我真正需要的是找到包含1 2和3位数字的所有3位数字
然后你可以安全地使用
grep('^[123]{3}$', a, value=TRUE)
##=> [1] "112" "123" "113" "212" "223" "213" "312" "323" "313"
正则表达式匹配:
^
- 字符串开头[123]{3}
- 正好3个字符1
,2
或3
$
- 在字符串末尾断言位置。此外,如果您只需要唯一值,请使用unique
。
如果您不需要多次允许相同的数字,则需要基于Perl的正则表达式:
grep('^(?!.*(.).*\\1)[123]{3}$', a, value=TRUE, perl=T)
## => [1] "123" "213" "312"
请注意双重转义的反向引用。 (?!.*(.).*\\1)
否定前瞻将检查字符串是否在捕获组(.)
的帮助下没有重复符号,并且后引用强制相同的捕获文本出现在字符串中。如果找到相同的字符,则不会匹配。请参阅IDEONE demo。
(?!.*(.).*\\1)
是negative look-ahead。它只声明在当前正则表达式引擎位置之后缺少某些模式,即如果没有匹配则检查并返回true,否则返回false。因此,它不会消费&#34;字符,它不匹配&#34;前瞻中的模式,正则表达式引擎停留在输入字符串中的相同位置。在这个正则表达式中,它是字符串(^
)的开头。因此,正好在字符串的开头,正则表达式引擎开始寻找.*
(任何字符,但换行符,0或更多重复),然后将1个字符(.)
捕获到组1中,再次匹配0或.*
的更多字符,然后尝试将组1中的相同文本与\\1
匹配。因此,如果有121
,则不会匹配,因为前瞻会返回 false ,因为它会找到两个1
。
答案 1 :(得分:1)