2012-09-14 56 views
1

我有一个不区分大小写的正则表达式:正则表达式:以前的声明必须mached至少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
  • T:0895555454
  • 传真:(08)9555 5353
  • 传真95555353
  • ˚F95 55 53 53

但我不希望这些匹配

  • (08)9555 5454

基本上,我想匹配我认定为电话号码的东西,但只有只有标识符。

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

任何想法?

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

回答

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问题 - 他的明确替代方案的解决方案更易于阅读,并且不太可能留下一些奇怪的边缘开放。

+0

您也需要从前瞻中排除':'。不过也许是更好的解决方案,那么我的后视解决方案将会可靠地要求匹配被锚定在字符串的开头。 – pmakholm

+0

嗨Cebjyre。非常好的想法,最后我去了这个:'(?= [^ \ s \ d \(:])f?a?(x | csim)?(mob)?(ile \ s *?)?(电话)?(e)?(电话| p | t | m)?\ s *?:?\ s *?(\ s *?\(*?\ d \)*?){8,10}'which是的,但考虑到区号的开头括号 –

+0

是的,我注意到基于pmakholm的':'建议的parens - 包含在第一段中的描述中,但是以某种方式将它排除在实际的正则表达式之外。现在修复。 – Cebjyre

0

这个怎么样:

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

我测试过了,恐怕它不工作:-( – Nelson

2

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

如果保留最小化到最小,这将有助于:

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

的将使前缀不可选的,并且还可以防止大量的垃圾被接受。例如:

axilep: (08) 9555 5454 
+0

严格地说,字符串仍然满足您的正则表达式,但是'axile'部分不匹配 - 在'\ b'(字边界断言)虽然 – Cebjyre

+0

感谢pmakholm,我感谢你的完整性水平,我确实接受我的正则表达式可能会匹配一些时髦的边缘情况,我可能会考虑匹配更直接的问题,但我正在这里工作的特定问题,它是不太重要,我在服务台请求中对字词用法进行了统计分析,我正在剥离像我们常见的电子邮件页脚以及任何看起来像电话号码的东西,但是谢谢,我没有发现axilep问题 –

0

或者回答你从字面上问题:

:您可以通过添加背后断言匹配正则表达式的部分之间的单个字符相匹配的前缀,其余零宽度的外观做
f?a?(x|csim)?(mob)?(ile\s*?)?(tel)?(e)?(phone|p|t|m)?(?<=.)\s*?:?\s*?(\s*?\(*?\d\)*?){8,10} 

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

相关问题