[编辑]注意:

最短的正则表达式是主要问题,而不是反向引用。



需求:

使用最短的正则表达式匹配以下格式的所有字符串:

<two digits><connect char><three digits><connect char><four digits>


为了易于阅读:

<two digits>
<connect char>
<three digits>
<connect char>
<four digits>


条件:


假设输入字符串为单行,则匹配整个字符串。
Connect字符可能都省略,或者是[-./ ]中的任何一个(不包括[])。
每个匹配的字符串中的两个connect char必须相同。
最短很重要,性能并不重要。




一些有效的字符串:

55.635.8828
72/683/1582
86 942 7682
581827998      // Both connect chars is omit


一些无效的字符串:

56.855/9856     // Two connect chars are different.
56 4559428      // Same as above


这个简短的正则表达式将匹配所有有效的字符串:

^\d{2}[-./ ]?\d{3}[-./ ]?\d{4}$


但它也匹配无效的:

52-355/9984


此正则表达式将匹配所有正确的字符串,但是会很长。我将其分解为多行以便于阅读:

^(\d{2}-?\d{3}-?\d{4})|
(\d{2}\.?\d{3}\.?\d{4})|
(\d{2}/?\d{3}/?\d{4})|
(\d{2} ?\d{3} ?\d{4})$


你能建议我一个较短的正则表达式满足要求吗?

最佳答案

您可以捕获分隔符并使用向后引用而不是重复模式

^\d\d([-./ ]?)\d{3}\1\d{4}$
     ^       ^     ^^


请参见regex demo

在C#中:

var isValid = Regex.IsMatch(s, @"^\d\d([-./ ]?)\d{3}\1\d{4}$");


如果只想将ASCII数字与RegexOptions.ECMAScript匹配(默认情况下在.NET regex中与all Unicode digits匹配),则将\d选项传递给regex编译器。

图案细节


^-字符串开始
\d\d-任意2位数字
([-./ ]?)-组1捕获1或0 -./或空格
\d{3}-任何3位数字
\1-与第1组中捕获的值相同
\d{4}-任意4位数字
$-字符串结尾(或者您可能要使用\z来确保字符串的确切结尾,但是在大多数情况下没有必要)。

07-25 20:30
查看更多