HTML 页面中的模式匹配
Pattern Match in an HTML Page
我无法对需要从中挖掘数据的页面使用 preg_match。在 $url 上获取内容通常会输出多个字符串,如下所示
https://www.zigsaw.in/companies-detail/AU-Small-Finance-Bank-Ltd/65344.html
这些字符串通常可以包含小字符、大字符、/、(、)、- 等。我想提取数据
- 在"company-detail/"
之后
- 在“.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);
但是,上面的代码没有获取
的预期结果
AU-Small-Finance-Bank-Ltd/65344.html
& 同样
TLDR:
使用这个:\bwww\.zigsaw\.in\/companies-detail\/\K[^\/]+\/[^\/]+(?=\.html)
解释:
你的正则表达式有几个问题
- 正则表达式通常由 '/' 字符分隔,因此如果您使用它们,则需要对这些字符进行转义。例如,
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
但仍然不匹配。那是因为字符 class [a-zA-Z0-9.()-]
不允许条 /
出现。
所以在这里,https://www.zigsaw.in/companies-detail/Foo-BAR-Bank/12345.html
当您匹配 https://www.zigsaw.in/companies-detail/Foo-BAR-Bank
时,您不能 "go on" 匹配,稍后您期望找到 .html,这是错误的。所以正则表达式失败了。
您通过向 class 添加一个条来解决这个问题,如下所示:
\b(https:\/\/www\.zigsaw\.in\/companies-detail\/)[a-zA-Z0-9.()\/-]+\b(.html)\b
或者您可以只使用:\b(https:\/\/www\.zigsaw\.in\/companies-detail\/)[^\/]+\/[^\/]+\b(.html)\b
,它将 class 更改为 [^\/]+\/[^\/]+
,这意味着任何不是竖线的字符,重复一次或多次,竖线,然后任何不是竖线的字符重复一次或多次。
我们还删除了 .html 之前的 \b
,因为它没有添加任何内容。
现在你遇到了只匹配你感兴趣的东西的问题。你可以像这样添加一个捕获组 \b(https:\/\/www\.zigsaw\.in\/companies-detail\/)([^\/]+\/[^\/]+)(.html)\b
并恢复第二组。
但是你也可以不捕获组来做到这一点:
和\K
我们将忽略所有之前匹配的数据。通过前瞻,我们 'match without matching'(我们只是检查下一个字符的一些模式,我们将它用于 \.html
)
所以你可以使用:
\bwww\.zigsaw\.in\/companies-detail\/\K[^\/]+\/[^\/]+(?=\.html)
我无法对需要从中挖掘数据的页面使用 preg_match。在 $url 上获取内容通常会输出多个字符串,如下所示
https://www.zigsaw.in/companies-detail/AU-Small-Finance-Bank-Ltd/65344.html
这些字符串通常可以包含小字符、大字符、/、(、)、- 等。我想提取数据
- 在"company-detail/" 之后
- 在“.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);
但是,上面的代码没有获取
的预期结果AU-Small-Finance-Bank-Ltd/65344.html
& 同样
TLDR:
使用这个:\bwww\.zigsaw\.in\/companies-detail\/\K[^\/]+\/[^\/]+(?=\.html)
解释:
你的正则表达式有几个问题
- 正则表达式通常由 '/' 字符分隔,因此如果您使用它们,则需要对这些字符进行转义。例如,
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
但仍然不匹配。那是因为字符 class [a-zA-Z0-9.()-]
不允许条 /
出现。
所以在这里,https://www.zigsaw.in/companies-detail/Foo-BAR-Bank/12345.html
当您匹配 https://www.zigsaw.in/companies-detail/Foo-BAR-Bank
时,您不能 "go on" 匹配,稍后您期望找到 .html,这是错误的。所以正则表达式失败了。
您通过向 class 添加一个条来解决这个问题,如下所示:
\b(https:\/\/www\.zigsaw\.in\/companies-detail\/)[a-zA-Z0-9.()\/-]+\b(.html)\b
或者您可以只使用:\b(https:\/\/www\.zigsaw\.in\/companies-detail\/)[^\/]+\/[^\/]+\b(.html)\b
,它将 class 更改为 [^\/]+\/[^\/]+
,这意味着任何不是竖线的字符,重复一次或多次,竖线,然后任何不是竖线的字符重复一次或多次。
我们还删除了 .html 之前的 \b
,因为它没有添加任何内容。
现在你遇到了只匹配你感兴趣的东西的问题。你可以像这样添加一个捕获组 \b(https:\/\/www\.zigsaw\.in\/companies-detail\/)([^\/]+\/[^\/]+)(.html)\b
并恢复第二组。
但是你也可以不捕获组来做到这一点:
和\K
我们将忽略所有之前匹配的数据。通过前瞻,我们 'match without matching'(我们只是检查下一个字符的一些模式,我们将它用于 \.html
)
所以你可以使用:
\bwww\.zigsaw\.in\/companies-detail\/\K[^\/]+\/[^\/]+(?=\.html)