首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PHP -内部HTML递归替换

PHP -内部HTML递归替换
EN

Stack Overflow用户
提问于 2014-02-12 21:28:38
回答 3查看 270关注 0票数 0

我需要在超文本标记语言的一部分上执行递归str_replace (对于递归,我是指首先执行内部节点),所以我写道:

代码语言:javascript
复制
$str = //get HTML;
$pttOpen = '(\w+) *([^<]{1,100}?)';
$pttClose = '\w+';
$pttHtml = '(?:(?!(?:<x-)).+)';

while (preg_match("%<x-(?:$pttOpen)>($pttHtml)*</x-($pttClose)>%m", $str, $match)) {
    list($outerHtml, $open, $attributes, $innerHtml, $close) = $match;
    $newHtml = //some work....
    str_replace($outerHtml, $newHtml, $str);
}

这个想法是首先替换非嵌套的x-tag。但它只有在innerHtml位于开始标记的同一行时才有效(所以我猜我误解了/m修饰符的作用)。我不想使用DOM库,因为我只需要简单的字符串替换。有什么帮助吗?

EN

回答 3

Stack Overflow用户

发布于 2014-02-12 21:41:29

试试这个正则表达式:

代码语言:javascript
复制
%<x-(?P<open>\w+)\s*(?P<attributes>[^>]*)>(?P<innerHtml>.*)</x-(?P=open)>%s

演示

http://regex101.com/r/nA2zO5

示例代码

代码语言:javascript
复制
$str = // get HTML
$pattern = '%<x-(?P<open>\w+)\s*(?P<attributes>[^>]*)>(?P<innerHtml>.*)</x-(?P=open)>%s';

while (preg_match($pattern, $str, $matches)) {
    $newHtml =  sprintf('<ns:%1$s>%2$s</ns:%1$s>', $matches['open'], $matches['innerHtml']);
    $str = str_replace($matches[0], $newHtml, $str);
}

echo htmlspecialchars($str);

输出

最初,$str包含以下文本:

代码语言:javascript
复制
<x-foo>
    sdfgsdfgsd
       <x-bar>
           sdfgsdfg
       </x-bar>
       <x-baz attr1='5'>
           sdfgsdfg
       </x-baz>
    sdfgsdfgs
</x-foo>

结果是:

代码语言:javascript
复制
<ns:foo>
   sdfgsdfgsd
   <ns:bar>
       sdfgsdfg
   </ns:bar>
   <ns:baz>
       sdfgsdfg
   </ns:baz>
   sdfgsdfgs
</ns:foo>

因为我不知道在$newHtml上做了什么工作,所以我以某种方式模仿了这项工作,用ns:替换了x-并删除了所有属性。

票数 1
EN

Stack Overflow用户

发布于 2014-02-13 01:34:11

感谢@Alex,我想出了这个:

代码语言:javascript
复制
%<x-(?P<open>\w+)\s*(?P<attributes>[^>]*?)>(?P<innerHtml>((?!<x-).)*)</x-(?P=open)>%is

如果在innerHtml模式中没有((?!,它将无法处理嵌套标记(它将首先匹配外部标记,这不是我想要的)。希望这能有所帮助。

票数 1
EN

Stack Overflow用户

发布于 2014-02-13 02:31:39

我不知道你到底想要做什么样的改变,但这就是我要做的:

代码语言:javascript
复制
$pattern = <<<'EOD'
~
    <x-(?<tagName>\w++) (?<attributes>[^>]*+) >
    (?<content>(?>[^<]++|<(?!/?x-))*) #by far more efficient than (?:(?!</?x-).)*
    </x-\g<tagName>>
~x
EOD;

function callback($m) { // exemple function
    return '<n-' . $m['tagName'] . $m['attributes'] . '>' . $m['content']
         . '</n-' . $m['tagName'] . '>';       
};

do {
    $code = preg_replace_callback($pattern, 'callback', $code, -1, $count);
} while ($count);


echo htmlspecialchars(print_r($code, true));
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21729287

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档