0

我想将第二个h2标签替换为h3,我希望有人可以帮助我替换正则表达式,或者可能是preg_split- 我不太确定。

例如,这个:

<h2>My text one</h2>
<h2>My text two</h2>
text …
<h2>My text three</h2>

应该变成这样:

<h2>My text one</h2>
<h3>My text two</h3>
text …
<h2>My text three</h2>
4

3 回答 3

2

我同意其他评论,这应该通过 dom 解析器来完成。但是这里有一个有效的 php 解决方案。

<?php 
     // Fill $str with the html;

     preg_replace("/[h]{1}[2]/i", "h3", $str);
?>

或者

<?php
     // Fill $str with the html;

     str_replace("h2", "h3", $str);      
?>

这应该工作得很好。将 $matches 参数添加到 preg_replace 也将跟踪所做的更改数量。现在,使用循环您可以控制需要替换哪个元素,但是,上面编写的函数将检测所有出现的 h2。

此外,为了让您能够换出数字,我将正则表达式过度复杂化,以使其具有更有用的功能。只需使用“/(h2)/i”也可以解决问题。

因此,您的代码应该以正确的方式实现循环以防止替换所有标签,并且您应该决定该函数是仅处理 h2 还是应该更灵活。

最后,str_replace 比 preg_replace 快,所以如果这是您需要进行的唯一编辑,我会推荐 str_replace。

于 2012-11-19T18:34:51.890 回答
2

您可以使用Javascript轻松做到这一点,真的需要使用 PHP 吗?

获取第二个<h2>

$text = $("h2:eq(1)").html();

毁灭它。

$("h2:eq(1)").remove();

<h3>在第一个之后创建一个<h2>,其中$text包含

$("h2:eq(0)").after("<h3>" + $text + "</h3>");
于 2012-11-19T18:42:51.683 回答
1

您不需要为此使用服务器端 HTML 解析器,这在 imo 中完全是矫枉过正。以下是一个显然可以被某些 HTML 结构破坏的示例,但对于大多数标记来说,它不会有任何问题 - 并且比服务器端 HTML 解析器更优化。

$html = '
<h2>My text one</h2>
<h2>My text two</h2>
text ...
<h2>My text three</h2>
';

preg_match_all

/// the following preg match will find all <h2> mark-up, even if 
/// the content of the h2 splits over new lines - due to the `s` switch
/// It is a non-greedy match too - thanks to the `.+?` so it shouldn't 
/// have problems with spanning over more than one h2 tag. It will only
/// really break down if you have a h2 as a descendant of a h2 - which
/// would be illegal html - or if you have a `>` in one of your h2's
/// attributes i.e. <h2 title="this>will break">Text</h2> which again
/// is illegal as they should be encoded.

preg_match_all(
  '#(<)h2([^>]*>.+?</)h2(>)#is',
  $html,
  $matches,
  PREG_OFFSET_CAPTURE|PREG_SET_ORDER
);

更换和重建

/// Because you wanted to only replace the 2nd item use the following. 
/// You could however make this code as general or as specific as you wanted.
/// The following works because the surrounding content for the found 
/// $matches was stored using the grouping brackets in the regular 
/// expression. This means you could easily change the regexp, and the 
/// following code would still work.

/// to get a better understanding of what is going on it would be best
/// to `echo '<xmp>';print_r( $matches );echo '/<xmp>';`

if ( isset($matches[1][0]) ) {
  $html = substr( $html, 0, $matches[1][0][1] ) . 
          $matches[1][1][0] . 'h3' . 
          $matches[1][2][0] . 'h3' . 
          $matches[1][3][0] .
          substr( $html, $matches[1][0][1] + strlen($matches[1][0][0]) );
}

我不知道为什么很多人说要使用客户端 JavaScript 来进行这种更改,PHP 代表PHP: Hypertext Preprocessor它旨在预处理超文本。OP 只提到过 PHP 函数,并用 PHP 标记了这篇文章,所以没有任何东西指向客户端。

诚然,虽然客户端可以并且应该尽可能地用于减轻服务器端的处理,但不建议将其用于诸如标题之类的核心结构标签——屏幕阅读器和搜索引擎机器人将依赖这些标签。最好使用客户端 JavaScript 来增强用户体验。如果您使用它来批判性地增强您网站的功能,您最好确保您的整个用户群都支持它。

但是,如果你们中的任何人提到Node.jsJSDOM,我会很高兴地同意。

于 2012-11-19T19:00:50.160 回答