【问题标题】:Regex only for specific domain name in URL正则表达式仅适用于 URL 中的特定域名
【发布时间】:2015-12-02 21:21:06
【问题描述】:

尽我所能,我似乎无法找到正确的正则表达式来找到我想要的内容。

我只想从以下内容中选择与域 www.myweb.com 匹配的 url 的第一个实例...

Some text https://www.myweb.com/page/cat/323123442321-rghe432 and then another https://www.adifferentsite.com/fsdhjss/erwr

我需要完全忽略第二个网址 www.adifferentsite.com,只使用与 www.myweb.com 匹配的第一个网址,忽略任何其他可能的实例www.myweb.com

一旦发现第一个匹配的域,我需要存储它之后的其余 url...

page/cat/323123442321-rghe432

...变成一个新的变量$newvar,所以...

$newvar = 'page/cat/323123442321-rghe432';

我正在尝试:

return preg_replace_callback( '/http://www.myweb.com/\/[0-9a-zA-Z]+/', array( __CLASS__, 'my_callback' ), $newvar );

我已经阅读了大量关于如何检测 url 的文档,但找不到任何关于检测特定 url 的信息。

我真的无法掌握如何制定正则表达式,所以这个公式是不正确的。任何帮助将不胜感激。

编辑将问题编辑得更具体一些,希望更容易解决。

【问题讨论】:

  • 如果需要匹配,为什么要替换?当您创建正则表达式时,您是否注意正则表达式分隔符?我猜你得到了一个未知的分隔符错误。
  • 我正在替换,因为我要将链接制定为 url 格式不同的 oEmbed 链接。所以myweb.com/page/cat/323123442321-rghe432在这个过滤器之后渲染时会变成embed.myweb.com/page/cat/323123442321-rghe432
  • 正则表达式,我只是不明白它是如何工作的。我读了又读,但似乎无法掌握正确的做法。
  • 好的,我认为您可以使用'~\bhttps?://www\.myweb\.com/(\S+)~' 正则表达式并将$m[1] 推送到“其余URL”的数组中。
  • 这是demo 我的意思。

标签: php regex


【解决方案1】:

您可以使用 preg_replace_callback 并将数组传递给匿名函数(或只是您的自定义回调函数),以使用所有必要的 URL 部分填充它。

这是demo

$rests = array();
$re = '~\b(https?://)www\.myweb\.com/(\S+)~'; 
$str = "Some text https://www.myweb.com/page/cat/323123442321-rghe432 and then another https://www.adifferentsite.com/fsdhjss/erwr"; 
echo $result = preg_replace_callback($re, function ($m) use (&$rests) {
    array_push($rests, $m[2]);
    return $m[1] . "embed.myweb.com/" . $m[2];
}, $str) . PHP_EOL;
print_r($rests);

结果:

Some text https://embed.myweb.com/page/cat/323123442321-rghe432 and then another https://www.adifferentsite.com/fsdhjss/erwr
Array
(
    [0] => page/cat/323123442321-rghe432
)

几句话:

  • '~\b(https?://)www\.myweb\.com/(\S+)~' 具有 ~ 作为 regex delimiter,因此您不必转义 /
  • 它是用单引号文字声明的,因此您不必对\\S 使用双重转义
  • 它匹配并捕获到 capturing groups 2 个子字符串:\b(https?://)(匹配整个单词 httphttps,后跟 ://)和 (\S+)(匹配1 个或多个非空白字符)。这些捕获组在模式中用(...) 标记,可以通过$matches[n] 访问,其中n 是捕获组的ID。

更新

如果您只需要替换 第一次出现的 URL,请将 limit 参数传递给preg_replace_callback

$rest = "";
$re = '~\b(https?://)www\.myweb\.com/(\S+\b)~'; 
$str = "Some text https://www.myweb.com/page/cat/323123442321-rghe432, another http://www.myweb.com/page/cat/323123442321-rghe432 and then another https://www.adifferentsite.com/fsdhjss/erwr"; 
echo $result = preg_replace_callback($re, function ($m) use (&$rest) {
    $rest = $m[2];
    return $m[1] . "embed.myweb.com/" . $m[2];
}, $str, 1) . PHP_EOL;
//-LIMIT ^ - HERE -
echo $rest;

another IDEONE demo

【讨论】:

  • 这很好用,但在这种情况下我不需要数组。我只需要匹配并收集第一个 url 实例的 url。这个例程可以不使用数组吗?
  • 您的意思是说您拥有Some text https://www.myweb.com/page1 and https://www.myweb.com/page2 并且只想替换第一个?使用1 作为preg_replace_callback 的最后一个参数。
  • 谢谢@stribizhev,这是完美的!
  • 使用否定字符类 [^/]* 匹配除 / 之外的 0 个或多个字符以留在 URL 部分中。见demo
  • 好的,使用this one$re = '~(https?://)www\.myweb\.com/(([^/]*/[^/]*)\S+\b)~'; 然后$result = preg_replace_callback($re, function ($m) use (&$rest) { $rest = $m[3]; return $m[1] . "embed.myweb.com/" . $m[2]; }, $str, 1)
猜你喜欢
  • 1970-01-01
  • 2016-08-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-20
  • 1970-01-01
  • 2016-04-21
相关资源
最近更新 更多