HTML页面中的模式匹配

时间:2018-08-08 10:55:04

标签: regex pattern-matching preg-match preg-match-all

我无法在需要从中挖掘数据的页面上使用preg_match。在$ url上获取内容通常会输出如下所示的多个字符串

  

https://www.zigsaw.in/companies-detail/AU-Small-Finance-Bank-Ltd/65344.html

这些字符串通常可以包含小字符,大字符,/,(,),-等。我想提取数据

  1. “公司详情/”之后
  2. “。html”之前

我使用的代码如下

$contents=file_get_contents($url);
$pattern='/\b(https://www.zigsaw.in/companies-detail/)\b+[a-zA-Z0-9.-()]+\b(.html)\b/';
preg_match_all($pattern, $contents, $matches);
var_dump($matches);

但是,以上代码未获取

的预期结果
  

澳大利亚小型金融银行有限公司/65344.html

&喜欢

1 个答案:

答案 0 :(得分:1)

TLDR:

使用此命令:\bwww\.zigsaw\.in\/companies-detail\/\K[^\/]+\/[^\/]+(?=\.html)

Demo

说明:

您在正则表达式上遇到了几个问题

  • 正则表达式通常以'/'字符分隔,因此如果使用它们,则需要对这些字符进行换码。例如,http://应该是http:\/\/
  • 尽管不会出现错误,但您应将点.换成\.,因为点表示除换行以外的任何字符。因此,www.在这里您可能是指文字点:www\.
  • 您具有以下构造:\b+,这是错误的。 \b表示裸字,而+重复一次或多次。这种组合没有意义。您可以通过将+改为文字+:\+来解决错误,但是,由于我认为这对您的正则表达式根本没有帮助,因此我只删除它们
  • [a-zA-Z0-9.-()]上,您应将最后一个-换成\.,因为破折号用于指定范围(如a-z)。另一种选择是像这样将其放在结尾:[a-zA-Z0-9.()-]

使用上述修复程序,您将获得:\b(https:\/\/www\.zigsaw\.in\/companies-detail\/)[a-zA-Z0-9.()-]+\b(.html)\b,但仍然不匹配。这是因为字符类[a-zA-Z0-9.()-]不允许出现小节/

因此,在这里https://www.zigsaw.in/companies-detail/Foo-BAR-Bank/12345.htmlhttps://www.zigsaw.in/companies-detail/Foo-BAR-Bank匹配时,您无法“继续”匹配,以后您会期望找到.html,这是错误的。因此regexp失败。

您可以通过在类中添加栏来解决此问题,如下所示:

\b(https:\/\/www\.zigsaw\.in\/companies-detail\/)[a-zA-Z0-9.()\/-]+\b(.html)\b

或者您也可以使用:\b(https:\/\/www\.zigsaw\.in\/companies-detail\/)[^\/]+\/[^\/]+\b(.html)\b,将类更改为[^\/]+\/[^\/]+,这意味着任何不是竖线的字符,重复一次或多次,再横杠,然后再输入不是竖线的任何字符一个酒吧重复一次或多次。

我们还删除了.html之前的\b,因为它没有添加任何内容。

现在,您遇到的问题是只匹配您感兴趣的事物。您可以添加一个像\b(https:\/\/www\.zigsaw\.in\/companies-detail\/)([^\/]+\/[^\/]+)(.html)\b这样的捕获组并恢复第二个组。

但是,您也可以在不捕获组的情况下做到这一点:

使用\K,我们将忽略所有先前匹配的数据。并提前查找,我们“不匹配就匹配”(我们只检查下一个字符的某些模式,将其用于\.html

因此您可以使用:

\bwww\.zigsaw\.in\/companies-detail\/\K[^\/]+\/[^\/]+(?=\.html)