【问题标题】:get everything between <tag> and </tag> with php [duplicate]使用 php 获取 <tag> 和 </tag> 之间的所有内容 [重复]
【发布时间】:2012-02-12 21:49:34
【问题描述】:

我正在尝试使用正则表达式在字符串中抓取一个字符串。

我看了又看,但我似乎找不到任何我必须工作的例子。

我需要获取 html 标签 以及它们之间的所有内容。

然后我需要从父字符串中拉出匹配的字符串,对两者进行操作,

然后将匹配的字符串放回父字符串中。

这是我的代码:

$content = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. &lt;code>Donec sed erat vel diam ultricies commodo. Nunc venenatis tellus eu quam suscipit quis fermentum dolor vehicula.&lt;/code>"
$regex='';
$code = preg_match($regex, $text, $matches);

我已经尝试过这些但没有成功:

$regex = "/<code\s*(.*)\>(.*)<\/code>/";
$regex = "/<code>(.*)<\/code>/";

【问题讨论】:

  • 小马托尼,他来了...Have you tried an HTML parser?
  • 并非如此,这与解析单个 BBcode 标签没有什么不同。上面没有属性,就是一个直&lt;code&gt;(.*)&lt;/code&gt;
  • @minitech 解析单个 BBcode 标签?听起来像是正则表达式的完美情况,让 Pear 参与如此简单的事情毫无意义。
  • 我只是在这里胡乱猜测,但鉴于他的要求,我认为您不必担心[NOPARSE] 或任何愚蠢的事情:这只是“我如何匹配THIS 字符串文字和 THAT 字符串文字”,其中字符串文字恰好是 XML 标记。字符串文字没有其他可能的变化,因此没有必要过度复杂化。
  • 你为什么在 30 分钟前发布了完全相同的问题?

标签: php regex


【解决方案1】:

您可以使用以下内容:

$regex = '#<\s*?code\b[^>]*>(.*?)</code\b[^>]*>#s';
  • \b 确保不会捕获拼写错误(如 &lt;codeS&gt;)。
  • 第一个模式[^&gt;]* 捕获带有属性(例如类)的标签的内容。
  • 最后,s 标志使用换行符捕获内容。

在此处查看结果:http://lumadis.be/regex/test_regex.php?id=1081

【讨论】:

  • 不过,它不适用于没有结束标签的标签。例如,它不适用于&lt;code id="me" /&gt;
  • 这是完全自然的,因为问题是捕获&lt;code&gt;...&lt;/code&gt;标签的内容,而不是捕获自闭合标签(与&lt;code&gt;标签无关)。
  • 而不是在标签之间选择整个文本,如何只选择选定的字符?
【解决方案2】:

这个功能对我有用

<?php

function everything_in_tags($string, $tagname)
{
    $pattern = "#<\s*?$tagname\b[^>]*>(.*?)</$tagname\b[^>]*>#s";
    preg_match($pattern, $string, $matches);
    return $matches[1];
}

?>

【讨论】:

  • 您能解释一下为什么您返回的是 $matches[1] 而不是 [0]?
  • $matches[0] 是您传递的代码的外部html。要获得 innerHtml 你应该得到 $matches[1]
  • 您必须添加它以换取更安全的方式:return isset($matches[1]) ? $matches[1] : false; 如果标签不存在,那么它将给出错误。
  • 这非常有效,应该是公认的答案,谢谢!
  • 一个标签有效,但它不适用于 p 标签
【解决方案3】:
$regex = '#<code>(.*?)</code>#';

使用#作为分隔符而不是/,因为这样我们就不需要在&lt;/code&gt;中转义/

正如 Phoenix 在下面发布的那样,.*? 用于使 .*(“任何东西”)在遇到 &lt;/code&gt;(称为“非贪婪量词”)之前匹配尽可能少的字符。这样,如果你的字符串是

<code>hello</code> something <code>again</code>

您将匹配 helloagain 而不仅仅是匹配 hello&lt;/code&gt; something &lt;code&gt;again

【讨论】:

  • 如果字符串包含多个&lt;code&gt;标签,应该是(.*?)(承认OP中的示例没有说明这一点)?
  • 我喜欢贪婪的选项
  • 我知道这已经很老了...但是...要非常小心上面发布的正则表达式。我以前在非常大的 XML 文档上使用过这种类型的正则表达式。关闭贪婪设置,否则您可能会遇到灾难性的回溯。
  • @Joe 为什么它不适用于像&lt;tag&gt;@github&lt;/tag&gt;,&lt;tag&gt;@gcal-work&lt;/tag&gt;, 这样的字符串(注意末尾的逗号)?......它只选择第一个标签......即@github .有什么想法吗?
  • @KhurshidAlam 您可能需要添加g 标志以使正则表达式“全局” - 即,使其返回所有匹配项而不仅仅是第一个匹配项。只需在结束分隔符后添加一个小写字母g,例如。 #&lt;tag&gt;(.*?)&lt;/tag&gt;#g
【解决方案4】:

您可以使用/&lt;code&gt;([\s\S]*)&lt;\/code&gt;/msU 这也抓住了 NEWLINES!

【讨论】:

  • 如果您需要一个非贪婪选项,只需在 * '/([\s\S]*?)/msU' 后加一个问号
  • 我以为你喜欢贪婪的选项,不要再吹捧非贪婪了:P
【解决方案5】:
function contentDisplay($text)
{
    //replace UTF-8
    $convertUT8 = array("\xe2\x80\x98", "\xe2\x80\x99", "\xe2\x80\x9c", "\xe2\x80\x9d", "\xe2\x80\x93", "\xe2\x80\x94", "\xe2\x80\xa6");
    $to = array("'", "'", '"', '"', '-', '--', '...');
    $text = str_replace($convertUT8,$to,$text);

    //replace Windows-1252
    $convertWin1252 = array(chr(145), chr(146), chr(147), chr(148), chr(150), chr(151), chr(133));
    $to = array("'", "'", '"', '"', '-', '--', '...');
    $text = str_replace($convertWin1252,$to,$text);

    //replace accents
    $convertAccents = array('À', 'Á', 'Â', 'Ã', 'Ä', 'Å', 'Æ', 'Ç', 'È', 'É', 'Ê', 'Ë', 'Ì', 'Í', 'Î', 'Ï', 'Ð', 'Ñ', 'Ò', 'Ó', 'Ô', 'Õ', 'Ö', 'Ø', 'Ù', 'Ú', 'Û', 'Ü', 'Ý', 'ß', 'à', 'á', 'â', 'ã', 'ä', 'å', 'æ', 'ç', 'è', 'é', 'ê', 'ë', 'ì', 'í', 'î', 'ï', 'ñ', 'ò', 'ó', 'ô', 'õ', 'ö', 'ø', 'ù', 'ú', 'û', 'ü', 'ý', 'ÿ', 'A', 'a', 'A', 'a', 'A', 'a', 'C', 'c', 'C', 'c', 'C', 'c', 'C', 'c', 'D', 'd', 'Ð', 'd', 'E', 'e', 'E', 'e', 'E', 'e', 'E', 'e', 'E', 'e', 'G', 'g', 'G', 'g', 'G', 'g', 'G', 'g', 'H', 'h', 'H', 'h', 'I', 'i', 'I', 'i', 'I', 'i', 'I', 'i', 'I', 'i', '?', '?', 'J', 'j', 'K', 'k', 'L', 'l', 'L', 'l', 'L', 'l', '?', '?', 'L', 'l', 'N', 'n', 'N', 'n', 'N', 'n', '?', 'O', 'o', 'O', 'o', 'O', 'o', 'Œ', 'œ', 'R', 'r', 'R', 'r', 'R', 'r', 'S', 's', 'S', 's', 'S', 's', 'Š', 'š', 'T', 't', 'T', 't', 'T', 't', 'U', 'u', 'U', 'u', 'U', 'u', 'U', 'u', 'U', 'u', 'U', 'u', 'W', 'w', 'Y', 'y', 'Ÿ', 'Z', 'z', 'Z', 'z', 'Ž', 'ž', '?', 'ƒ', 'O', 'o', 'U', 'u', 'A', 'a', 'I', 'i', 'O', 'o', 'U', 'u', 'U', 'u', 'U', 'u', 'U', 'u', 'U', 'u', '?', '?', '?', '?', '?', '?');
    $to = array('A', 'A', 'A', 'A', 'A', 'A', 'AE', 'C', 'E', 'E', 'E', 'E', 'I', 'I', 'I', 'I', 'D', 'N', 'O', 'O', 'O', 'O', 'O', 'O', 'U', 'U', 'U', 'U', 'Y', 's', 'a', 'a', 'a', 'a', 'a', 'a', 'ae', 'c', 'e', 'e', 'e', 'e', 'i', 'i', 'i', 'i', 'n', 'o', 'o', 'o', 'o', 'o', 'o', 'u', 'u', 'u', 'u', 'y', 'y', 'A', 'a', 'A', 'a', 'A', 'a', 'C', 'c', 'C', 'c', 'C', 'c', 'C', 'c', 'D', 'd', 'D', 'd', 'E', 'e', 'E', 'e', 'E', 'e', 'E', 'e', 'E', 'e', 'G', 'g', 'G', 'g', 'G', 'g', 'G', 'g', 'H', 'h', 'H', 'h', 'I', 'i', 'I', 'i', 'I', 'i', 'I', 'i', 'I', 'i', 'IJ', 'ij', 'J', 'j', 'K', 'k', 'L', 'l', 'L', 'l', 'L', 'l', 'L', 'l', 'l', 'l', 'N', 'n', 'N', 'n', 'N', 'n', 'n', 'O', 'o', 'O', 'o', 'O', 'o', 'OE', 'oe', 'R', 'r', 'R', 'r', 'R', 'r', 'S', 's', 'S', 's', 'S', 's', 'S', 's', 'T', 't', 'T', 't', 'T', 't', 'U', 'u', 'U', 'u', 'U', 'u', 'U', 'u', 'U', 'u', 'U', 'u', 'W', 'w', 'Y', 'y', 'Y', 'Z', 'z', 'Z', 'z', 'Z', 'z', 's', 'f', 'O', 'o', 'U', 'u', 'A', 'a', 'I', 'i', 'O', 'o', 'U', 'u', 'U', 'u', 'U', 'u', 'U', 'u', 'U', 'u', 'A', 'a', 'AE', 'ae', 'O', 'o');
    $text = str_replace($convertAccents,$to,$text);

    //Encode the characters
    $text = htmlentities($text);

    //normalize the line breaks (here because it applies to all text)
    $text = str_replace("\r\n", "\n", $text);
    $text = str_replace("\r", "\n", $text);

    //decode the <code> tags
    $codeOpen = htmlentities('<').'code'.htmlentities('>');
    if (strpos($text, $codeOpen))
    {
        $text = str_replace($codeOpen, html_entity_decode(htmlentities('<')) . "code" . html_entity_decode(htmlentities('>')), $text);
    }
    $codeOpen = htmlentities('<').'/code'.htmlentities('>');
    if (strpos($text, $codeOpen))
    {
        $text = str_replace($codeOpen, html_entity_decode(htmlentities('<')) . "/code" . html_entity_decode(htmlentities('>')), $text);
    }

    //match everything between <code> and </code>, the msU is what makes this work here, ADD this to REGEX archive
    $regex = '/<code>(.*)<\/code>/msU';
    $code = preg_match($regex, $text, $matches);
    if ($code == 1)
    {
        if (is_array($matches) && count($matches) >= 2)
        {
            $newcode = $matches[1];

            $newcode = nl2br($newcode);
        }

    //remove <code>and this</code> from $text;
    $text = str_replace('<code>' . $matches[1] . '</code>', 'PLACEHOLDERCODE1', $text);

    //convert the line breaks to paragraphs
    $text = '<p>' . str_replace("\n\n", '</p><p>', $text) . '</p>';
    $text = str_replace("\n" , '<br />', $text);
    $text = str_replace('</p><p>', '</p>' . "\n\n" . '<p>', $text);

    $text = str_replace('PLACEHOLDERCODE1', '<code>'.$newcode.'</code>', $text);
    }
    else
    {
        $code = false;
    }

    if ($code == false)
    {
        //convert the line breaks to paragraphs
        $text = '<p>' . str_replace("\n\n", '</p><p>', $text) . '</p>';
        $text = str_replace("\n" , '<br />', $text);
        $text = str_replace('</p><p>', '</p>' . "\n\n" . '<p>', $text);
    }

    return $text;
}

【讨论】:

  • 这段庞大的代码应该包含一些解释。
【解决方案6】:

你也可以试试:

function getTagValue($string, $tag)
{
    $pattern = "/<{$tag}>(.*?)<\/{$tag}>/s";
    preg_match($pattern, $string, $matches);
    return isset($matches[1]) ? $matches[1] : '';
}

如果不匹配则返回空字符串。

【讨论】:

    【解决方案7】:

    检索或删除脚本标签的内容,即使是 &lt;script async&gt; 等特殊情况。

    $str = '
    Some js embed
    <script async>
      alert("js")
      let job, origin = new Date().getTime()
    </script>
    <span id="OUT"></span>
    <button onclick="alert()">RESET</button>
    timer experiment
    ';
    
    $reg = '/<script([\s\S]*)<\/script>/';
    
    preg_match($reg, $str, $matches);
    $match = substr($matches[0], (strpos($matches[0], ">")+1));
    $match = str_replace("</script>", "", $match);
    echo $match;
    /* OUTPUT
      alert("js")
      let job, origin = new Date().getTime()
    */
    echo "\n---------------------\n";
    echo preg_replace($reg, "DELETED", $str);
    /* OUTPUT
      Some js embed
      DELETED
      <span id="OUT"></span>
      <button onclick="alert()">RESET</button>
      timer experiment
    */
    

    【讨论】:

    • 这不是回答 OP 的具体问题。这个答案属于另一个问题。此外,在查询 html 文档时,应该使用 DOM 解析器,而不是正则表达式。
    猜你喜欢
    • 2014-03-26
    • 2016-09-16
    • 1970-01-01
    • 2016-05-12
    • 2012-10-15
    • 1970-01-01
    • 1970-01-01
    • 2019-12-21
    相关资源
    最近更新 更多