2

我为自己设置了这个听起来相当简单的挑战,但现在我一直在试图弄清楚如何将类名注入到<body>我的文档的 dom 元素中

复杂性是因为我无法控制通过该file_get_contents函数获得的 HTML 标记(第三方通过 FTP 提供文件)。

所以body元素可以有多种不同的方式,例如:

<body>
<body id="my-id" data-attribute="content">
<body data-attribute="content">
<body class="already-existing-class" id="my-id" data-attribute="content">

依此类推……甚至所述属性的顺序都不受我的控制,因此您可能在此class=之前有一个id=等等。

我想你们都明白我在这里谈论的复杂性;(我希望)

我基本上需要的是一种方法,用于preg_replace()将新类注入到如果已经存在)上的现有属性中,或者属性本身与我的新类一起添加到其中。classbodyclass

任何帮助将非常感激。

如果已经回答了这个问题,请随时指出。我尝试搜索,但使用这样的通用术语很难找到我要找的东西。

谢谢阅读。

J。

4

4 回答 4

3

为了提供一个接近正则表达式的解决方案,只要额外的空格不打扰你,这就是有效的;-)

<?php

$pat = '/(<body) ?(([^>]*)class="([^"]*)")?/';
$inp = '<body>
<body id="my-id" data-attribute="content">
<body data-attribute="content">
<body class="already-existing-class" id="my-id" data-attribute="content">
<body id="my-id" data-attribute="content" class="abc">';

echo preg_replace($pat, '$1 $3 class="$4 new-class" ', $inp);

?>

检查ideone的输出。

于 2011-12-15T01:40:32.343 回答
2

对于此应用程序,正则表达式可能非常麻烦。相反,我建议您使用 HTML 解析器,例如 PHP 的 DOMDocument。这是一个例子。

$node1 = '<body>';
$node2 = '<body id="my-id" data-attribute="content">';
$node3 = '<body data-attribute="content">';
$node4 = '<body class="already-existing-class" id="my-id" data-attribute="content">';

foreach( range( 1, 4) as $i)
{
    $var = 'node'.$i;
    $doc = new DOMDocument();
    $doc->loadHTML( $$var);
    foreach( $doc->getElementsByTagName( 'body') as $tag)
    {
        $tag->setAttribute('class', ($tag->hasAttribute('class') ? $tag->getAttribute('class') . ' ' : '') . 'some-new-class');
    }
    echo htmlentities( $doc->saveHTML()) . "\n";
}

演示

注意<body>标签的输出是正确的。您(或其他 SO 成员)可以自由决定如何从 DOMDocument 中仅提取正文标记。

于 2011-12-15T01:32:18.173 回答
1
$str = '<body>
<body id="my-id" data-attribute="content">
<body data-attribute="content">
<body class="already-existing-class" id="my-id" data-attribute="content">
';

$my_new_class = "HELLO_WORLD";
preg_match_all("/<body(.*?)>/is", $str, $m);
$s = sizeof($m[1]);
for($i=0; $i<$s; $i++){
    $m[1][$i] = preg_replace("/class=\"(.*?)\"/is", "class=\"".$my_new_class."\"", $m[1][$i]);
    if(!preg_match("/class=/is", $m[1][$i])){
        $m[1][$i] .= " class=\"".$my_new_class."\"";
    }
    $m[1][$i] = "<body".$m[1][$i].">";
}

print_r($m);
[1] => Array
    (
        [0] => <body class="HELLO_WORLD">
        [1] => <body id="my-id" data-attribute="content" class="HELLO_WORLD">

        [2] => <body data-attribute="content" class="HELLO_WORLD">
        [3] => <body class="HELLO_WORLD" id="my-id" data-attribute="content">
    )
于 2011-12-15T01:36:03.073 回答
0

应该更改正则表达式,因为 class="" 后面的任何内容都丢失了

/(<ul) ?(([^>]*)class="([^"]*)"([^>]*))?/

测试代码如下。您可以将 ul 替换为 body 标签

    <?php
    $pattern = '/(<ul) ?(([^>]*)class="([^"]*)"([^>]*))?/';
    $input_string = '<ul id="test" data-content="the content" class="children" data-compare="equal"><li> test</li></ul>';

    echo preg_replace($pattern, '$1 $3 class="$4 new-class" $5 ', $input_string);

    ?>

在图像中,您可以看到找到的每个变量的内容 ($1..$5)

使用 RegEx 表达式添加类名

示例可以在这里测试https://regex101.com/r/yjQe6G/1

于 2022-02-15T08:48:29.713 回答