1

我有一个不区分大小写的正则表达式:

f?a?(x|csim)?(mob)?(ile\s*?)?(tel)?(e)?(phone|p|t|m)?\s*?:?\s*?(\s*?\(*?\d\)*?){8,10}

这是我的测试用例:

我希望这些匹配:

  • 电话:9555 5454
  • 电话 08 9555 5454
  • 手机 0411111 111
  • 暴民 0411 111 111
  • 手机:(0411) 111 111
  • 电话:(08) 9555 5454
  • M0411111111
  • 电话:(08) 9555 5454
  • 电话:(08)95 55 54 54
  • 电话:0895555454
  • 传真:(08) 9555 5353
  • 传真95555353
  • 女 95 55 53 53

但我不希望这些匹配

  • 0411 111 111
  • (08) 9555 5454
  • 0411111111

基本上,我想匹配我识别为电话号码的东西,但前提是它们前面有一个标识符。

我的正则表达式将成功匹配前缀标识符,但由于整个事情是非贪婪的,“不匹配”测试用例失败,因为我的正则表达式指定“匹配前缀,如果它存在,但不需要它”。

有任何想法吗?

  • 请注意:我使用的是 Perl/PHP 版本的正则表达式。
4

4 回答 4

2

我的建议是保持正则表达式简单。您当前的正则表达式已经包含所需的前缀,但是最小化正则表达式大小的工作偶然使它们成为可选的。

如果您将最小化保持在最低限度,它将有所帮助:

\b(tel(ephone)?|mob(ile)?|facsimile|fax|[tmpf]):?\s?(\(\d+\))(\d|\s)+

这将使前缀非可选,并防止大量垃圾被接受。例如:

axilep: (08) 9555 5454
于 2012-09-14T09:35:42.997 回答
1

您可以在比赛开始时对空格、数字、括号或冒号以外的内容进行积极的前瞻

所以你的:

f?a?(x|csim)?(mob)?(ile\s*?)?(tel)?(e)?(phone|p|t|m)?\s*?:?\s*?(\s*?\(*?\d\)*?){8,10}

变成:

(?=[^\s\d:()])f?a?(x|csim)?(mob)?(ile\s*?)?(tel)?(e)?(phone|p|t|m)?\s*?:?\s*?(\s*?\(*?\d\)*?){8,10}

但是,这对 pmakholm 指出的 axilep 问题没有帮助 - 他的显式替代解决方案更易于阅读,并且您不太可能留下一些奇怪的边缘情况。

于 2012-09-14T10:09:03.707 回答
0

那这个呢:

(f?a?(x|csim)?(mob)?(ile\s*?)?(tel)?(e)?(phone|p|t|m)?)(?(1)\s*?:?\s*?(\s*?\(*?\d\)*?){8,10})
于 2012-09-14T09:15:26.963 回答
0

或者从字面上回答您的问题:您可以通过在与前缀匹配的正则表达式部分和其余部分之间匹配单个字符的断言后面添加一个零宽度的外观来做到这一点:

f?a?(x|csim)?(mob)?(ile\s*?)?(tel)?(e)?(phone|p|t|m)?(?<=.)\s*?:?\s*?(\s*?\(*?\d\)*?){8,10}

这意味着在找到前缀的匹配项后,需要再次查看是否确实存在字符。

于 2012-09-14T09:41:33.803 回答