将大写字母H1、H2,。。。使用PHP将标签转换为大写标题

将大写字母H1、H2,。。。使用PHP将标签转换为大写标题,php,regex,Php,Regex,我想把大写的h1,h2,。。。使用PHP将标记转换为大写文本。我很接近,但还没到那里。下面的代码段没有将“LOREM”的第一个字符转换为大写(可能是因为它尝试使用大写“/i”, 函数($matches){ 返回ucfirst(strtolower($matches[0]); }, $var ); 打印(行); 结果: <h1>lorem ipsum dolores amet</h1> THIS IS SOME TEXT <H2>lorem ipsum dol

我想把大写的h1,h2,。。。使用PHP将标记转换为大写文本。我很接近,但还没到那里。下面的代码段没有将“LOREM”的第一个字符转换为大写(可能是因为它尝试使用大写“/i”, 函数($matches){ 返回ucfirst(strtolower($matches[0]); }, $var ); 打印(行); 结果:

<h1>lorem ipsum dolores amet</h1>
THIS IS SOME TEXT
<H2>lorem ipsum dolores amet</H2>
lorem ipsum dolores amet
这是一些文本
洛雷姆·伊普苏姆·多洛雷斯·阿梅特
期望输出:

<h1>Lorem ipsum dolores amet</h1>
THIS IS SOME TEXT
<H2>Lorem ipsum dolores amet</H2>
Lorem ipsum dolores amet
这是一些文本
洛雷姆·伊普苏姆·多洛雷斯·阿梅特

它不是
$matches[0]
,而是
$matches[1]
matches[0]
指的是整个匹配(即,
ucfirst
strtolower
函数适用于整个匹配),而
$matches[1]
指的是组索引1中存在的字符。因为我们在正则表达式中包含了
,所以它与起始的
标记匹配。但在替换部分中,我们只包括组索引1,如
ucfirst(strtolower($matches[1])
。因此,开始的
标记被删除。请参见下面的示例

$var = "
<h1>LOREM IPSUM DOLORES AMET</h1>
THIS IS SOME TEXT
<H2>LOREM IPSUM DOLORES AMET</H2>";

$line = preg_replace_callback(
    '/<h[1-9]>(.*)\>/i',
    function ($matches) {
        return ucfirst(strtolower($matches[1]));
    },
    $var
);

print($line);
输出:

Lorem ipsum dolores amet</h1
THIS IS SOME TEXT
Lorem ipsum dolores amet</h2
<h1>Lorem ipsum dolores amet</h1>
THIS IS SOME TEXT
<H2>Lorem ipsum dolores amet</H2>
Lorem ipsum dolores amet
这是一些文本
洛雷姆·伊普苏姆·多洛雷斯·阿梅特

\K
在期末打印时放弃先前匹配的字符
*?
将对任何字符进行零次或多次非贪婪匹配
(?=它不是
$matches[0]
,它是
$matches[1]
匹配[0]
指整个匹配(即,
ucfirst
strtolower
函数适用于整个匹配),而
$matches[1]
指的是组索引1中存在的字符。因为我们在正则表达式中包含了
,所以它与开始的
标记匹配。但是在替换部分中,我们只包含了组索引1,如
ucfirst(strtolower($matches[1])
。因此开始的
标记被删除。请参见下面的示例

$var = "
<h1>LOREM IPSUM DOLORES AMET</h1>
THIS IS SOME TEXT
<H2>LOREM IPSUM DOLORES AMET</H2>";

$line = preg_replace_callback(
    '/<h[1-9]>(.*)\>/i',
    function ($matches) {
        return ucfirst(strtolower($matches[1]));
    },
    $var
);

print($line);
输出:

Lorem ipsum dolores amet</h1
THIS IS SOME TEXT
Lorem ipsum dolores amet</h2
<h1>Lorem ipsum dolores amet</h1>
THIS IS SOME TEXT
<H2>Lorem ipsum dolores amet</H2>
Lorem ipsum dolores amet
这是一些文本
洛雷姆·伊普苏姆·多洛雷斯·阿梅特

\K
在期末打印时放弃先前匹配的字符。
*?
将对任何字符进行零次或多次非贪婪匹配
(?=您将使用
$matches[0]
返回整个匹配。在本例中使用

我建议在第一个
标记中使用一个捕获组,以便您可以将其用作反向引用;因此,您将匹配与该组匹配的相同结束标记

$text = preg_replace_callback('~<h([1-9])>\K[^<]++(?=</h\1>)~i', 
      function($m) {
         return ucfirst(strtolower($m[0]));
      }, $text);

您正在使用
$matches[0]
返回整个匹配项。请在本例中使用

我建议在第一个
标记中使用一个捕获组,以便您可以将其用作反向引用;因此,您将匹配与该组匹配的相同结束标记

$text = preg_replace_callback('~<h([1-9])>\K[^<]++(?=</h\1>)~i', 
      function($m) {
         return ucfirst(strtolower($m[0]));
      }, $text);
不需要正则表达式

不需要正则表达式


使用
DOMDocument

<?php

        $var = "
<h1>LOREM IPSUM DOLORES AMET</h1>
THIS IS SOME TEXT
<H2>LOREM IPSUM DOLORES AMET</H2>";

        $dom = new DOMDocument();
        $dom->loadHTML($var);

        $tags = array("h1", "h2");
        //loop thru all h1 and h2 tags

        foreach ($tags as $tag) {
            //get all elements of the current tag
            $elements = $dom->getElementsByTagName($tag);
            //if we found at least 1 element
            if (!empty($elements)) {
                //loop thru each element of the given tag
                foreach ($elements as $element) {
                    //run ucfirst on the nodevalue
                    //which is equivalent to the "textContent" property of a DOM node
                $element->nodeValue = ucfirst(strtolower($element->nodeValue));
                }
            }
        }

$html = $dom->saveHTML();
//remove extra markup
$html = str_replace("</body></html>","",substr($html,strpos($html,"<h1>"));
echo $html;

<h1>Lorem ipsum dolores amet</h1>
THIS IS SOME TEXT
<h2>Lorem ipsum dolores amet</h2>

使用
DOMDocument

<?php

        $var = "
<h1>LOREM IPSUM DOLORES AMET</h1>
THIS IS SOME TEXT
<H2>LOREM IPSUM DOLORES AMET</H2>";

        $dom = new DOMDocument();
        $dom->loadHTML($var);

        $tags = array("h1", "h2");
        //loop thru all h1 and h2 tags

        foreach ($tags as $tag) {
            //get all elements of the current tag
            $elements = $dom->getElementsByTagName($tag);
            //if we found at least 1 element
            if (!empty($elements)) {
                //loop thru each element of the given tag
                foreach ($elements as $element) {
                    //run ucfirst on the nodevalue
                    //which is equivalent to the "textContent" property of a DOM node
                $element->nodeValue = ucfirst(strtolower($element->nodeValue));
                }
            }
        }

$html = $dom->saveHTML();
//remove extra markup
$html = str_replace("</body></html>","",substr($html,strpos($html,"<h1>"));
echo $html;

<h1>Lorem ipsum dolores amet</h1>
THIS IS SOME TEXT
<h2>Lorem ipsum dolores amet</h2>

$matches[0]
是整个匹配项;如果您希望第一个捕获组是
$matches[1]
。在我写答案时,请阅读以下内容:[不要用regex.Ever解析HTML。][1][1]:@deceze是的,但它有一些缺点。@谢谢你提醒我注意这一点。幸运的是,修改后将进行人工验证,以保证输出的质量。
$matches[0]
是整个匹配;如果你想要第一个捕获组,它将是
$matches[1]
。在我写答案时,请阅读以下内容:[永远不要用正则表达式解析HTML。][1][1]:@deceze是的,但它有一些缺点。@Tek感谢您提醒我注意这一点。幸运的是,修改后将进行人工验证,以保证输出的质量。阅读后,千万不要使用正则表达式来解析HTML,此解决方案已被选为正确答案,尽管它不能从字面上回答问题。很高兴它对你有用。除非任务非常简单,否则我总是更喜欢DOM解析器而不是正则表达式。这是堆栈溢出乐趣的一部分!答案可能是“为什么要这样做?改为这样做”答案在阅读了《永远不应该使用正则表达式解析HTML》之后,这个解决方案被选为正确答案,尽管它并没有从字面上回答这个问题。很高兴它能为您工作。除非任务非常简单,否则我总是更喜欢DOM解析器而不是正则表达式。这是堆栈溢出乐趣的一部分!而不是“这是你怎么做的”答案你可能会得到一个“你为什么要这样做?改为这样做”的答案