Php preg_match:通过匹配其中的一个单词来返回整个url
如果我有包含以下内容的文本:Php preg_match:通过匹配其中的一个单词来返回整个url,php,regex,preg-match,Php,Regex,Preg Match,如果我有包含以下内容的文本: 测试 如何通过匹配具有“abc=xxxx”的单词来预匹配,因此我得到: www.example.com/test?abc=xxxx&def=yyyy&ghi=zzzzz 当您在此处搜索URL时,有必要弄清楚它与上下文的区别 URL通常不包含空格,并且通常包含在某种引号或括号中,以便于识别: URL——被空格包围-- “URL”--在您的示例中引用-- --标记URL的类方法-- 这将允许将URL描述为以下表达式 ~(?P[^\s“\']+)~ 在您的示例中,仅
测试
如何通过匹配具有“abc=xxxx”的单词来预匹配,因此我得到:
www.example.com/test?abc=xxxx&def=yyyy&ghi=zzzzz
当您在此处搜索URL时,有必要弄清楚它与上下文的区别
URL通常不包含空格,并且通常包含在某种引号或括号中,以便于识别:
URL——被空格包围--
“URL”--在您的示例中引用--
--标记URL的类方法--
这将允许将URL描述为以下表达式
~(?P[^\s“\']+)~
在您的示例中,仅在文档上运行此操作已经在这里做了一些工作,它给出了13个结果,其中12个是误报,但URL位于:
#1 h1、#2测试、#3/h1、,
#4部分,5个html,6个元素,
#7 a,#8 href=,
#9 www.example.com/test?abc=xxxx&def=yyyy&ghi=zzzzz,
#10/a、#11更多、#12 html、,
#13个要素。
幸运的是,在您的案例中,URL是什么,您有更多的条件,因此可以添加这些条件。例如,必须有一个查询字符串。它必须包含一个问号:
~(?P[^\s“\'?]+\?[^\s“\'?]+)~
问号已被排除在允许的字符组之外,该组已被分割为两个,并且在中间需要问号。因为URL只能包含一次,所以这是完全好的。
现在只剩下一场比赛了www.example.com/test?abc=xxxx&def=yyyy&ghi=zzzzz
因为这现在真的很难读,让我们把它写下来:
~
(?(DEFINE)
(?<Chars> [^\s<>"\'?]+)
)
(?P<url> (?&Chars) \? (?&Chars) )
~x
因此,只要您对特定URL感兴趣,使用正则表达式执行此操作就相对简单,但是:文档中的URL不能被规范化,其他类似问题也可能会被规范化。因此,通常最值得先规范化URL,然后再继续进行。例如,在查询信息部分中查找URL参数时
在编写本文时,我实际上认为,对从文档中获取的URL的过滤应该独立于解析方法。正如其他用户所评论的,您可能希望使用HTML解析器而不是正则表达式。或者您可能希望两者都使用
让我们首先考虑正则表达式场景。下面是一个具有正确URL解析的正则表达式变体。作为预防措施,URL的最大长度限制在6到256字节之间:
$matcher = new PregStringMatcher('~([^\s<>"\']{6,256})~');
$segments = new StringMatcherIterator($matcher, $input);
$all = new DecoratingIterator($segments, 'Net_URL2');
$urls = new CallbackFilterIterator($all, function (Net_URL2 $url) {
return isset($url->getQueryVariables()['abc']);
});
foreach ($urls as $url) {
echo $url->getQueryVariables()['abc'], ' - ', $url, "\n";
}
如果你现在考虑切换到HTML解析器,你就不需要改变太多的代码。因为过滤逻辑保持不变,你只需要交换下面的<强>可遍历< /强>:
$doc = new DOMDocument();
$saved = libxml_use_internal_errors(true);
$doc->loadHTML($input);
libxml_use_internal_errors($saved);
$attributes = (new DOMXPath($doc))->query('//@href');
$segments = new DecoratingIterator($attributes, function (DOMAttr $attr) {
return $attr->nodeValue;
});
代码的其余部分可以保持不变,本例中的结果是相同的。因此,我希望这些示例非常有用,并展示了如何处理regex模式以及如何添加更多检查的一些方法
下面是带有正则表达式和HTML解析器的完整代码示例。URL筛选器在这两个方面都是相同的:
<?php
/**
* preg_match: return entire url by matching a word inside it
*
* @link http://stackoverflow.com/a/29481904/367456
*/
require __DIR__ . '/vendor/autoload.php';
$input = <<<BUFFER
<h1> Test </h1>
<some html elements>
<a href="www.example.com/test?%61%62%63=xxxx&def=yyyy&ghi=zzzzz"></a>
<more html elements>
BUFFER;
// Regex based retrieval
$matcher = new PregStringMatcher('~([^\s<>"\']{6,256})~');
$segments = new StringMatcherIterator($matcher, $input);
$all = new DecoratingIterator($segments, 'Net_URL2');
$urls = new CallbackFilterIterator($all, function (Net_URL2 $url) {
return isset($url->getQueryVariables()['abc']);
});
foreach ($urls as $url) {
echo $url->getQueryVariables()['abc'], ' - ', $url, "\n";
}
// DOMDocument based retrieval
$doc = new DOMDocument();
$saved = libxml_use_internal_errors(true);
$doc->loadHTML($input);
libxml_use_internal_errors($saved);
$attributes = (new DOMXPath($doc))->query('//@href');
$segments = new DecoratingIterator($attributes, function (DOMAttr $attr) {
return $attr->nodeValue;
});
$all = new DecoratingIterator($segments, 'Net_URL2');
$urls = new CallbackFilterIterator($all, function (Net_URL2 $url) {
return isset($url->getQueryVariables()['abc']);
});
foreach ($urls as $url) {
echo $url->getQueryVariables()['abc'], ' - ', $url, "\n";
}
您尝试过什么吗?^在问题中添加您的尝试您应该解析url和查询字符串,而不是使用正则表达式。如果该文本是html,则使用DOM和一些xpath。//a[contains(@href,'abc=')]
?我很高兴看到评论。好吧。要学习DOM+xpath吗
$doc = new DOMDocument();
$saved = libxml_use_internal_errors(true);
$doc->loadHTML($input);
libxml_use_internal_errors($saved);
$attributes = (new DOMXPath($doc))->query('//@href');
$segments = new DecoratingIterator($attributes, function (DOMAttr $attr) {
return $attr->nodeValue;
});
<?php
/**
* preg_match: return entire url by matching a word inside it
*
* @link http://stackoverflow.com/a/29481904/367456
*/
require __DIR__ . '/vendor/autoload.php';
$input = <<<BUFFER
<h1> Test </h1>
<some html elements>
<a href="www.example.com/test?%61%62%63=xxxx&def=yyyy&ghi=zzzzz"></a>
<more html elements>
BUFFER;
// Regex based retrieval
$matcher = new PregStringMatcher('~([^\s<>"\']{6,256})~');
$segments = new StringMatcherIterator($matcher, $input);
$all = new DecoratingIterator($segments, 'Net_URL2');
$urls = new CallbackFilterIterator($all, function (Net_URL2 $url) {
return isset($url->getQueryVariables()['abc']);
});
foreach ($urls as $url) {
echo $url->getQueryVariables()['abc'], ' - ', $url, "\n";
}
// DOMDocument based retrieval
$doc = new DOMDocument();
$saved = libxml_use_internal_errors(true);
$doc->loadHTML($input);
libxml_use_internal_errors($saved);
$attributes = (new DOMXPath($doc))->query('//@href');
$segments = new DecoratingIterator($attributes, function (DOMAttr $attr) {
return $attr->nodeValue;
});
$all = new DecoratingIterator($segments, 'Net_URL2');
$urls = new CallbackFilterIterator($all, function (Net_URL2 $url) {
return isset($url->getQueryVariables()['abc']);
});
foreach ($urls as $url) {
echo $url->getQueryVariables()['abc'], ' - ', $url, "\n";
}