regexp - 以任何顺序查找字符串中的数字

时间:2015-10-01 11:28:22

标签: regex r

我需要找一个正则表达式,它允许我找到我拥有所有必需数字但只有一次的字符串。

例如:

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"

2 个答案:

答案 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个字符123
  • $ - 在字符串末尾断言位置。

此外,如果您只需要唯一值,请使用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)

你也可以使用这个

grep('^([123])((?!\\1)\\d)(?!\\2|\\1)\\d', a, value=TRUE, perl=T)

请参阅demo