使用 RegEx 仅允许字符出现两个实例

使用 RegEx 仅允许字符出现两个实例

我是使用正则表达式的新手,我正在尝试找出一些看似相当简单的东西。我想确定一个字符是否在字符串中只出现两次。该字符不必连续出现两次,但字符串中任何地方都出现两次即可。例如,“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]。)

相关内容