正则表达式/通配符替换字符串PHP

时间:2013-05-03 01:02:22

标签: php regex

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

<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"开头并以/>

结尾的字符串

我已经展示了我所追求的步骤,以及我对它的刺痛。请帮我写,最后了解如何做。我真的很茫然。

2 个答案:

答案 0 :(得分:2)

你写的正则表达式到处都是。我们来看看这个模式:

无论发生什么,它都会以<link开头,以></link>/>结束(需要考虑那些讨厌的不尊重标准的网络海盗)。你正在寻找rel参数,如果它有一个,它需要是规范的。

我们可以开始编写正则表达式:#<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标记而产生的歧义。

  • ()表示必须匹配要返回的字符串的单独“表达式”? ()匹配一个子集,如果为匹配项指定变量,则允许您将其返回到结果中。正则表达式的每个部分都可以使用通配符&amp; co,但只包含在()中的东西将在比赛中返回

  • ^过滤以下列字符串开头的结果? 不。 a []范围之外的^将匹配开始的任何内容与以下字符串句点。在新的一条线上,不仅仅是“言辞”。
  • 结果的$过滤器以以下字符串结尾? 与上面相同,只是“结束”而不是“开始”。

答案 1 :(得分:1)

快速入门说明:不建议使用正则表达式解析HTML,而是使用DomDocument或其他一些“DOM解析”附加组件。但由于这只是使用1个句子的字符串,这就是我接近它的方式:

<?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