【问题标题】:php regex, extract like phone number regex from html documentsphp 正则表达式,从 html 文档中提取类似电话号码的正则表达式
【发布时间】:2011-02-24 22:00:38
【问题描述】:

我正在尝试从不同的 html 页面中提取特定信息。基本上,信息是一个 10 位数字,可能有不同的形式:

000-000-0000 000 - 000 - 0000 0000000000 请注意,000 - 000 - 0000000 不是有效的电话号码,因此如果它包含任何附加数字,则不应提取该号码

对于创建适用于所有 3 种情况的完美正则表达式的任何帮助,我将不胜感激。到目前为止,我只能让它对最后一个(最简单的)起作用。

【问题讨论】:

  • 我很抱歉造成混乱,我最初关闭了不正确的副本。您是否有机会尝试匹配 (X)HTML 标记内的电话号码?
  • 您似乎对每个与您所寻找的答案不符的答案都投了反对票。这将阻止人们尝试帮助您,尤其是在容易出错的正则表达式问题中。自发布以来,您还更改了问题;您的 000 - 000 - 0000000 反例不在第一次编辑中,因此@Jeff 的答案满足原始要求。我注意到他仍然投反对票。我这样说并不是出于对自己投反对票的担忧,更多的是为了帮助您和网站的整体健康。

标签: php regex


【解决方案1】:

这将匹配您列出的所有三个示例。

(\d{3}\s*-?\s*\d{3}\s*-?\s*\d{4})

【讨论】:

  • +1 比我的简洁多了。我想我需要复习一下我的 regex-foo :)
  • 基本上是一样的,只是少了一些不必要的字符。我爱我一些正则表达式。
  • 是的,我不记得 - 是否是一个特殊字符,所以我选择了安全路线。
  • 正则表达式并不完美 .. 它发现 212-642-288455 有效(提取 212-642-2884)
  • 完美是罕见的,尤其是在正则表达式中。 +1。
【解决方案2】:

这是一个很好的起点:

<?php 

// all on one line... 
$regex = '/^(?:1(?:[. -])?)?(?:\((?=\d{3}\)))?([2-9]\d{2})(?:(?<=\(\d{3})\))? ?(?:(?<=\d{3})[.-])?([2-9]\d{2})[. -]?(\d{4})(?: (?i:ext)\.? ?(\d{1,5}))?$/';

// or broken up 
$regex = '/^(?:1(?:[. -])?)?(?:\((?=\d{3}\)))?([2-9]\d{2})' 
        .'(?:(?<=\(\d{3})\))? ?(?:(?<=\d{3})[.-])?([2-9]\d{2})' 
        .'[. -]?(\d{4})(?: (?i:ext)\.? ?(\d{1,5}))?$/'; 

?> 

注意非捕获子模式(看起来像(?:stuff))。这使格式化变得容易:

<?php 

$formatted = preg_replace($regex, '($1) $2-$3 ext. $4', $phoneNumber); 

// or, provided you use the $matches argument in preg_match 

$formatted = "($matches[1]) $matches[2]-$matches[3]"; 
if ($matches[4]) $formatted .= " $matches[4]"; 

?>

还有一些示例结果:

520-555-5542 :: MATCH 
520.555.5542 :: MATCH 
5205555542 :: MATCH 
520 555 5542 :: MATCH 
520) 555-5542 :: FAIL 
(520 555-5542 :: FAIL 
(520)555-5542 :: MATCH 
(520) 555-5542 :: MATCH 
(520) 555 5542 :: MATCH 
520-555.5542 :: MATCH 
520 555-0555 :: MATCH 
(520)5555542 :: MATCH 
520.555-4523 :: MATCH 
19991114444 :: FAIL 
19995554444 :: MATCH 
514 555 1231 :: MATCH 
1 555 555 5555 :: MATCH 
1.555.555.5555 :: MATCH 
1-555-555-5555 :: MATCH 
520-555-5542 ext.123 :: MATCH 
520.555.5542 EXT 123 :: MATCH 
5205555542 Ext. 7712 :: MATCH 
520 555 5542 ext 5 :: MATCH 
520) 555-5542 :: FAIL 
(520 555-5542 :: FAIL 
(520)555-5542 ext .4 :: FAIL 
(512) 555-1234 ext. 123 :: MATCH 
1(555)555-5555 :: MATCH

如果您允许像您建议的那样使用空格和破折号,您可能会得到很多误报。

【讨论】:

  • 对我来说看起来不错,而且您已经完成了一些非常详尽的测试,这很棒。 +1。
  • 非常好!只需要评论这个答案的质量。
【解决方案3】:

\b[0-9]{3}\s*[-]?\s*[0-9]{3}\s*[-]?\s*[0-9]{4}\b

编辑

添加了单词边界。

【讨论】:

  • 正则表达式并不完美 .. 它发现 212-642-288455 有效(提取 212-642-2884)-
  • 你不需要 - 周围的 [],但无论如何它应该可以工作。 +1。
【解决方案4】:

考虑除连字符之外的其他分隔符,更不用说括号了。

(?:1\s*?[-.]?\s*)?(?:\(\s*d{3}\s*\)|d{3})\s*?[-.]?\s*\d{3}\s*?[-.]?\s*\d{4}\b

好的,也许这比您需要的更全面,但实际上这可以变得任意复杂。您可以扩展它以查找国际电话号码、分机号等,但这对您来说可能不值得。

【讨论】:

  • 我认为它根本不起作用... $htmlContent = "834-343-3434"; $pattern = "/(?:1\s*?[-.]?\s*)?(?:(\\sd{3}\s*)|d{3})\s?[-.]?\s*\d{3}\s*?[-.]?\s*\d{4}\b/"; preg_match_all($pattern, $htmlContent, $matches); print_r($matches);
  • @Michael:我不确定 \\s 是如何进入那里的。已编辑。仅供参考,除非答案非常明显错误或适得其反,否则对诚实尝试但失败的事情投反对票通常被认为是不好的形式。
【解决方案5】:
<?php
preg_match_all("/\+?[0-9][\d-\()-\s+]{5,12}[1-9]/", $string, $matches);
print_r($matches);
?>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-01-27
    • 1970-01-01
    • 2011-12-14
    • 1970-01-01
    • 1970-01-01
    • 2017-09-23
    • 2014-02-15
    相关资源
    最近更新 更多