什么正则表达式可以匹配一个模式或者为空?

13

我需要一个可以匹配模式或为空的正则表达式。

目前我有一个表达式...

"\(?\d{3}\)?[-\s.]?\d{3}[-\s.]\d{4}/x"

......匹配美国电话号码。然而,测试字符串为空是有效的。如果字符串中有任何值,则必须与表达式匹配。

我还有其他模式可以匹配美国邮政编码等,它们需要相同的条件。

在同一表达式中实现这一点的最佳方法是什么?

澄清:我正在使用来自Microsoft的验证应用程序块中的RegexValidator。以下是使用此功能的示例:

[StringLengthValidator(0, 100, MessageTemplate = "Email must be between {3} and {5}")]
[RegexValidator(@"\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*", MessageTemplate = "Valid Email Required.")]
public string EmailAddress
{
    get { return _EmailAddress; } 
    set { SetValue<string>(ref _EmailAddress, value); }
}

这就是为什么我需要解决方案只能用一个表达式来实现。


你的正则表达式末尾的 /x 是什么意思?在 Perl 或 PHP 中,它表示自由空格模式,但 .NET 不使用该语法。 - Alan Moore
啊,其实不知道。我只是从某个网站上复制过来的。我会把它删除看看是否有帮助。 - Sailing Judo
3个回答

30

将整个正则表达式用括号括起来,并在末尾加上一个问号:

(\(?\d{3}\)?[-\s.]?\d{3}[-\s.]\d{4}/x)?

运行得非常好。我知道这只是一些简单的东西。 :) - Sailing Judo
2
实际上...这个不起作用。尾随的问号似乎使正则表达式过于宽容。例如,555-1234现在会匹配,但它不应该。 - Sailing Judo
假设您的原始正则表达式有效,您可以尝试: \B|\(?\d{3}\)?[-\s.]?\d{3}[-\s.]\d{4}/x 这应该是“空字符串”或者是您的正则表达式。 - Kevin Crowell
相同的问题。我的原始正则表达式(没有/x)在这个测试网站(http://www.nvcc.edu/home/drodgers/ceu/resources/test_regexp.asp)上可以工作。如果我添加您建议的选项,那么我可以输入任何内容进行测试,并且它都会通过。 - Sailing Judo
感谢阿伦的说明。我实际上从未使用\B。 - Kevin Crowell
显示剩余2条评论

2
尝试使用(?:<your_regex>)?将你的正则表达式包装起来。

1

试试这个:

@"^(?:(\()?\d{3}(?(1)\)|[-\s.])\d{3}[-\s.]\d{4})?$"

(?(1)\)|[-\s.]) 部分是一个条件构造。它的意思是:“如果在开头有一个'('(我们知道这一点是因为第一组匹配了某些内容),则在此处匹配一个')';否则匹配一个连字符、空格或点。”将整个内容包装在(?:...)?中允许它匹配一个空字符串,就像Kevin所说的那样;如果这对你不起作用,你必须错放了其中一个括号(或者可能是其中一个反斜杠)。

我添加了^$锚点进行测试;在验证控件中,它们不应该是必需的。


有趣的是,你的正则表达式完全崩溃了我一直在使用的表达式检查网站(http://www.nvcc.edu/home/drodgers/ceu/resources/test_regexp.asp)。不过,还是给你加1分,因为总体思路是可行的。 - Sailing Judo
你知道那个网站是否使用了.NET正则表达式引擎吗?这里可以正常工作:http://derekslager.com/blog/posts/2007/09/a-better-dotnet-regular-expression-tester.ashx - Alan Moore

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接