我是使用正则表达式的新手,我正在尝试找出一些看似相当简单的东西。我想确定一个字符是否在字符串中只出现两次。该字符不必连续出现两次,但字符串中任何地方都出现两次即可。例如,“41:08:05”是可以的,但“41:08”或“41:08:05:02”则不正确。在此示例中,我正在寻找字符串中任何地方只存在两个冒号 (:)。
答案1
我将用英语讲解这一点,指出正则表达式的每个部分,然后展示它的实际应用。我将回答您提出的具体问题,然后指出一些可能更适合您的解决方案的替代方案。
您希望模式以字符串的开头,这样我们就不会匹配以我们所需的模式作为子字符串的字符串。表示字符串的开头是^
。
然后,第一个字符之前可能会有一些字符:
。根据你问的问题的措辞,字符:
是字符串中的第一个字符是可以接受的,所以我们将寻找零个或多个不是 的字符。“不是:
的字符”的正则表达式组是,其后跟的是 的正则表达式字符:
[^:]
零个或多个,*
。
然后,我们要匹配第一个:
。我们可以使用普通字符来实现:
。
然后,我们再寻找零个或多个不是 的字符:
。同样,根据你问题的措辞,冒号相邻是没有问题的。因此,我们将添加另一个[^:]*
。
然后,我们将匹配另一个平原:
。
最后,我们将有零个或多个非:
字符,然后是字符串结尾。解释成正则表达式,那就是[^:]*$
。
把所有这些放在一起,我们就得到了您所要求的东西:
[gnubeard@mothership: ~]$ echo '41:08:05' | egrep '^[^:]*:[^:]*:[^:]*$'
41:08:05
[gnubeard@mothership: ~]$ echo '41:08:05:02' | egrep '^[^:]*:[^:]*:[^:]*$'
[gnubeard@mothership: ~]$ echo '41:08' | egrep '^[^:]*:[^:]*:[^:]*$'
[gnubeard@mothership: ~]$
这确实允许出现如下情况:
[gnubeard@mothership: ~]$ echo '::' | egrep '^[^:]*:[^:]*:[^:]*$'
::
[gnubeard@mothership: ~]$ echo ':abcdefg###:' | egrep '^[^:]*:[^:]*:[^:]*$'
:abcdefg###:
如果您想要像您给出的示例字符串那样格式化的内容,您需要确保非:
字符存在、为数字并且一次出现两个。我将把这一项的解释留给读者作为练习。
[gnubeard@mothership: ~]$ echo '41:08:05' | egrep '^[[:digit:]]{2}:[[:digit:]]{2}:[[:digit:]]{2}$'
41:08:05
[gnubeard@mothership: ~]$ echo '41:08' | egrep '^[[:digit:]]{2}:[[:digit:]]{2}:[[:digit:]]{2}$'
[gnubeard@mothership: ~]$ echo '41:08:05:02' | egrep '^[[:digit:]]{2}:[[:digit:]]{2}:[[:digit:]]{2}$'
[gnubeard@mothership: ~]$ echo '::' | egrep '^[[:digit:]]{2}:[[:digit:]]{2}:[[:digit:]]{2}$'
[gnubeard@mothership: ~]$ echo 'aa:bb:cc' | egrep '^[[:digit:]]{2}:[[:digit:]]{2}:[[:digit:]]{2}$'
[gnubeard@mothership: ~]$
请注意,这是使用egrep
正则表达式而不是正则表达式引擎c#
使用的,但两者足够类似,您应该能够轻松找到相应的语法(最大的区别是[[:digit:]]
字符类,在其他正则表达式引擎中通常可以表示为[0-9]
。)