我要找到一个正则表达式来匹配所有没有重复数字的数字序列。例子:
198345 -> 匹配。
198315 -> 不匹配(1 重复两次)
我怎样才能实现这一目标grep\egrep
?
答案1
有趣的问题。谢谢。我觉得这个答案有点令人毛骨悚然:
egrep -v '([0-9])[0-9]*\1'
模式找到数字的出现[0-9]
,将其保存\1
并检查不重复。所以它会找到任何数字后跟相同的数字。用于-v
逆
答案2
如果您需要使用正则表达式来执行此操作,请参阅斯蒂芬对类似问题的精彩回答。
如果正则表达式不是必须的,我为您提供 Perl 替代方案:
perl -nle '
$digits{$_}++ for /([0-9])/g;
@repeated = grep { $digits{$_} > 1 } keys %digits;
print @repeated? "":"$_"
%digits = ();
' your_file
这假设your_file
每行有一个数字,并且只会打印那些数字唯一的数字。
答案3
编辑:
下面相同的数字必须连续出现:它们匹配 1123456(连续 1)但不匹配 1213456(非连续 1):
一个蹩脚的解决方案是这样的:
cat testfile | grep [0-9] | grep -v "0\{2,\}" | grep -v "1\{2,\}" | grep -v "2\{2,\}" | grep -v "3\{2,\}" | grep -v "4\{2,\}" | grep -v "5\{2,\}" | grep -v "6\{2,\}" | grep -v "7\{2,\}" | grep -v "8\{2,\}" | grep -v "9\{2,\}"
第一个grep
匹配数字,其余 10 个grep
确保每个数字仅出现一次。
一个更紧凑但仍然蹩脚的方式是这样的:
cat test | grep [0-9] | grep -v "1\{2,\}\|2\{2,\}\|3\{2,\}\|4\{2,\}\|5\{2,\}\|6\{2,\}\|7\{2,\}\|8\{2,\}\|9\{2,\}\|0\{2,\}"
testfile
每行必须有一个单词。
答案4
grep '\([[:digit:]]\) *\1 *\1'
它需要一个数字[[:digit:]]
并记住它\( ... \)
。然后,它会尝试匹配任意数量的空格*
(包括根本没有空格)、记住字符\1
、任意数量的空格、记住的字符。您可以尝试运行它以--color=auto
查看它匹配输入的哪些部分。