使用正则表达式匹配给定条件下的字符串

时间:2017-11-09 13:28:44

标签: c# regex string-matching

[编辑]注意:

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

要求:

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

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

为方便阅读:

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

条件:

  • 匹配整个字符串,假设输入字符串是单行。
  • 连接字符可以省略,也可以是[-./ ]中的任何一个(不包括[])。
  • 每个匹配字符串中的两个连接字符必须相同
  • 最短很重要,性能并不重要。

实施例

一些有效的字符串:

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})$

您能否建议我使用符合要求的较短正则表达式?

1 个答案:

答案 0 :(得分:3)

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

^\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正则表达式中匹配all Unicode digits),请将\d选项传递给正则表达式编译器。

模式详情

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