4

我有大量文本加载到标题中,其中包含此链接。

<link rel="canonical" href="could_be_anything_here_at_all" />

我希望用新值替换它,但 href 会根据页面更改,这意味着不可能进行简单的 str_replace。

我看过使用 preg_replace,但无法理解似乎是一个简单的问题。

    $regex = '/(^<link rel="canonical")(\/>$)/';
    $match = preg_match_all($regex, $content, $matches);
    var_dump($matches);
  • //开始和结束表达式?
  • () 表示必须与要返回的字符串匹配的单独“表达式”?
  • ^ 过滤以以下字符串开头的结果?
  • $ 过滤以以下字符串结尾的结果?

所以我正在寻找一个以开头<link rel="canonical"和结尾的字符串/>

我已经展示了我所追求的步骤,以及我的努力。请帮助我写作并最终了解如何去做。我真的在这个方面不知所措。

4

2 回答 2

2

你写的正则表达式到处都是。让我们回顾一下模式:

无论发生什么,它都会以or开头<link和结尾(必须说明那些讨厌的不遵守标准的网络海盗)。您正在寻找 rel 参数,如果它有一个,并且它需要是规范的。></link>/>

我们可以开始编写正则表达式:#<link([^>]+)(/>|></link>)#is. 这将映射所有link标签。然后,您可以使用简单的strpos调用来解析参数。

如果您确定 rel="canonical" 将是链接标签的第一个参数,您可以将正则表达式进一步扩展为#<link rel="canonical" href="?'?([^"']+)"?'?(/>|></link>)#is. 这将按顺序映射它,如果您确定这是顺序,那很好。

按出场顺序:

[^>]+匹配除>字符之外的任何内容一次或多次

标志代表is:不区分大小写,不要换行

"?'?匹配 0 或 1 ",后跟 0 或 1 '

如果还有什么不清楚的,请告诉我。

编辑:回答你的问题

  • //开始和结束表达式? 它们被称为分隔符,它们“封装”表达式。Perl 正则表达式引擎允许设置有关表达式(i、s、g、b 等)的标志,并且这些标志必须在表达式之外。他们追随分隔符 - 这就是分隔符的重点。你可以使用任何你喜欢的角色——它会选择最远的两个重复的角色。人们倾向于使用 / 由于 JS 为他们使用单个字符 - 我倾向于在 PHP 中使用 # 来清除关闭 HTML 标记引起的歧义。

  • () 表示必须与要返回的字符串匹配的单独“表达式”? () 匹配一个子集,如果您为匹配项指定一个变量,则允许您在结果中取回它。正则表达式的每个部分都可以使用通配符 & co,但只有 () 中的内容才会在匹配中返回

  • ^ 过滤以以下字符串开头的结果? 没有。[] 范围之外的 ^ 将匹配以以下字符串句号开头的任何内容。在一个新的行上,有效地,不仅仅是“单词”。
  • $ 过滤以以下字符串结尾的结果? 同上,只是“结束”而不是“开始”。
于 2013-05-03T01:09:23.363 回答
1

Quick starting note: It is not recommended to parse HTML using regular expressions, but rather DomDocument, or some other "DOM parsing" add-on. But since this is only using a 1 sentence string, this is how I would approach it:

<?php
// base string
$str = '<link rel="canonical" href="could_be_anything_here_at_all" />';

// for preg_replace
$preg_replace = '<link rel="canonical" href="'.preg_replace('/<link rel="canonical" href="(.*)" \/>/','MY_NEW_LINK',$str).'" />';
echo $preg_replace;

// preg_match_all
preg_match_all('/<link rel="canonical" href="(.*)" \/>/',$str,$preg_match);
echo '<pre>',print_r($preg_match),'</pre>'; // process as you wish
于 2013-05-03T01:15:17.090 回答