【问题标题】:Get value from "url" parameter of url querystring which is & delimited从 & 分隔的 url 查询字符串的“url”参数中获取值
【发布时间】:2020-11-01 06:37:09
【问题描述】:

我正在使用PHP 7.4.1

我正在尝试解析来自 google 的 rss 提要。

我的链接如下所示:

https://www.google.com/url?rct=j&sa=t&url=https://www.timeslive.co.za/sunday-times/news/2020-11-01-hawks-following-former-steinhoff-ceo-markus-joostes-money/&ct=ga&cd=CAIyGjRm
https://www.google.com/url?rct=j&sa=t&url=https://www.politifact.com/factchecks/2020/oct/31/raphael-warnock/fact-checking-raphael-warnocks-claim-georgia-sen-k/&ct=ga&cd=CAIyGm
https://www.google.com/url?rct=j&sa=t&url=https://www.benzinga.com/news/20/10/18156683/last-weeks-notable-insider-buys-ibm-intel-raytheon-and-more&ct=ga&cd=CAIyGmM3Yjk5YjRlYWU
https://www.google.com/url?rct=j&sa=t&url=https://stocksregister.com/2020/10/31/insider-trading-at-avino-silver-gold-mines-ltd-nyseasm-what-did-we-note/&ct=ga&cd=CAIyGmM3Yjk5Y
https://www.google.com/url?rct=j&sa=t&url=https://www.businessinsider.co.za/who-received-an-sms-from-markus-jooste-2020-10&ct=ga&cd=CAIyGmM3Yjk5YjRlYWU3MWY2MDY6Y29tOmVuOlVT&am
https://www.google.com/url?rct=j&sa=t&url=https://stocksregister.com/2020/10/31/insider-trading-at-veritone-inc-nasdaqveri-what-did-we-note/&ct=ga&cd=CAIyGmM3Yjk5YjRlYWU3MWY2M
https://www.google.com/url?rct=j&sa=t&url=https://heavy.com/sports/las-vegas-raiders/jj-watt-stephon-gilmore-trade-targets/&ct=ga&cd=CAIyGmM3Yjk5YjRlYWU3MWY2MDY6Y29tOmVuOlVT&a
https://www.google.com/url?rct=j&sa=t&url=https://stocksregister.com/2020/10/31/insider-trading-at-truecar-inc-nasdaqtrue-what-did-we-note/&ct=ga&cd=CAIyGmM3Yjk5YjRlYWU3MWY2MD
https://www.google.com/url?rct=j&sa=t&url=https://stocksregister.com/2020/10/31/insider-trading-at-veeco-instruments-inc-nasdaqveco-what-did-we-note/&ct=ga&cd=CAIyGmM3Yjk5YjRl
https://www.google.com/url?rct=j&sa=t&url=https://stocksregister.com/2020/10/31/insider-trading-at-21vianet-group-inc-nasdaqvnet-what-did-we-note/&ct=ga&cd=CAIyGmM3Yjk5YjRlYWU

我想从url=获取真正的链接并剪掉结尾/&ct=ga&cd=CAIyGjRm

我尝试了str_replace,但是由于不同,解析出结尾很困难。

对如何获取链接有什么建议吗?

【问题讨论】:

  • 似乎最后一个标记始终是要省略的所需标记。 @mickmackusa
  • @mickmackusa 我从谷歌警报 rss 提要中获得这些链接。收到的链接如上所示。
  • OP 只想要查询字符串中的一个值——当 php 已经提供了一个 url 解析器时,正则表达式似乎是一个不合适的工具。

标签: php url extract query-string parse-url


【解决方案1】:

当没有合法/原生/可靠的技术来解析文本时,正则表达式是合适的。

PHP 提供本地函数来解析 url 和查询字符串。

以下 sn-p 涉及多个本机函数,其执行速度将比正则表达式慢,但当您的外部数据源重新配置其查询字符串数据时,它也将非常不可能中断。例如,如果他们添加了一个额外的参数rawurl=,那么正则表达式很容易错误地匹配这些。使用合法解析技术或正则表达式(在 url、有效 html、bbcode 等上)之间的争论太常见了——但开发人员的主要目标应该始终是数据完整性。如果您正在处理大量数据,并且速度提升实际上为您的系统/最终用户提供了宝贵的好处,那么只有为了执行速度而牺牲数据完整性。如果您发现自己没有充分理由倾向于微优化解决方案,我建议您不要喝那种酷爱饮料。

这是解析 url 并提取 url 值的一种方式。

代码:(Demo)

$url = 'https://www.google.com/url?rct=j&sa=t&url=https://www.timeslive.co.za/sunday-times/news/2020-11-01-hawks-following-former-steinhoff-ceo-markus-joostes-money/&ct=ga&cd=CAIyGjRm';

parse_str(
    htmlspecialchars_decode(
        parse_url(
            $url,
            PHP_URL_QUERY
        )
    ),
    $parts
);
echo $parts['url'];

输出:

https://www.timeslive.co.za/sunday-times/news/2020-11-01-hawks-following-former-steinhoff-ceo-markus-joostes-money/

我超级喜欢正则表达式,但不是每项任务都适用。在此避免使用正则表达式将使您的脚本更易读、更可靠且更易于维护。

【讨论】:

  • 当然是。您知道 OP 正在 10,000,000 个网址上执行此操作吗?这不是关于微优化,而是关于一种可靠的解决方案,该解决方案具有可读性和可维护性,并且不需要 IT 团队中的每个人都了解正则表达式。
  • 现在我希望您对提供的 10 个 url 运行相同的基准测试,并告诉我脚本在这两种技术之间会滞后多少分钟。如果 OP 隔离 10,000,000 个 url 的查询字符串值,那我肯定会支持使用正则表达式来节省 14 秒。
  • 正确,你错过了我回答的重点。在 10 个 url 上,没有人会注意到这些答案之间的性能差异。我也对在有效 HTML 上使用 regex-vs-dom-parser 提出了相同的论点——当输入突然改变其格式/结构时,解析器静默失败的可能性要小得多。这是无处可去。你不会让我相信我对这些选项还不了解的任何事情,所以我将不参与你的微优化辩论。
  • 这显然是最合适的答案。使用该工作的专用工具可以使代码更可靠、不那么晦涩、更易于维护。在 95% 的真实场景中,微优化不会产生任何明显的差异。所以在 95% 的情况下,这是更好的答案。由于 OP 没有提到他正在处理多少个 URL,所以还不如走安全可靠的方式。
  • @FlashThunder 因此,如果有人要求使用正则表达式来解析整个 HTML 文档,您不会强烈建议 consider not 吗?如果有人标记他们的问题mysql-real-escape-string,你不会强烈建议他们考虑使用准备语句吗?标签大多只是表明 OP 正在考虑从哪些解决方案开始。如果他们考虑了其中的几个,他们会在他们的实际帖子中说明这一点,并解释为什么他们特别需要正则表达式。但他们没有,所以可能没关系。
【解决方案2】:

您可以在preg_match_all 中使用此正则表达式:

(?<=url=)https?:\S+?(?=&amp;|$)

RegEx Demo

正则表达式详细信息:

  • (?&lt;=url=):如果我们在当前位置之前有url=
  • https?:\S+?:匹配以http:https:开头的URL
  • (?=&amp;amp;|$): 如果我们有&amp;amp; 或者当前位置之后的行结束

代码:

php > $s = "https://www.google.com/url?rct=j&amp;sa=t&amp;url=https://www.timeslive.co.za/sunday-times/news/2020-11-01-hawks-following-former-steinhoff-ceo-markus-joostes-money/&amp;ct=ga&amp;cd=CAIyGjRm";
php > preg_match_all('~(?<=url=)https?:\S+?(?=&amp;|$)~', $s, $m);
php > print_r($m[0]);
Array
(
    [0] => https://www.timeslive.co.za/sunday-times/news/2020-11-01-hawks-following-former-steinhoff-ceo-markus-joostes-money/
)

【讨论】:

  • 当我在preg_matchpreg_match_all 函数中运行正则表达式时出现错误:preg_match(): Unknown modifier 'h' 有什么建议为什么它不采用该模式?
  • 我在我的答案中添加了一个示例 php 代码。请检查
猜你喜欢
  • 2020-06-12
  • 2017-07-20
  • 1970-01-01
  • 2017-10-07
  • 1970-01-01
  • 1970-01-01
  • 2019-02-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多