我需要在超文本标记语言的一部分上执行递归str_replace (对于递归,我是指首先执行内部节点),所以我写道:
$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库,因为我只需要简单的字符串替换。有什么帮助吗?
发布于 2014-02-12 21:41:29
试试这个正则表达式:
%<x-(?P<open>\w+)\s*(?P<attributes>[^>]*)>(?P<innerHtml>.*)</x-(?P=open)>%s演示
http://regex101.com/r/nA2zO5
示例代码
$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包含以下文本:
<x-foo>
sdfgsdfgsd
<x-bar>
sdfgsdfg
</x-bar>
<x-baz attr1='5'>
sdfgsdfg
</x-baz>
sdfgsdfgs
</x-foo>结果是:
<ns:foo>
sdfgsdfgsd
<ns:bar>
sdfgsdfg
</ns:bar>
<ns:baz>
sdfgsdfg
</ns:baz>
sdfgsdfgs
</ns:foo>因为我不知道在$newHtml上做了什么工作,所以我以某种方式模仿了这项工作,用ns:替换了x-并删除了所有属性。
发布于 2014-02-13 01:34:11
感谢@Alex,我想出了这个:
%<x-(?P<open>\w+)\s*(?P<attributes>[^>]*?)>(?P<innerHtml>((?!<x-).)*)</x-(?P=open)>%is如果在innerHtml模式中没有((?!,它将无法处理嵌套标记(它将首先匹配外部标记,这不是我想要的)。希望这能有所帮助。
发布于 2014-02-13 02:31:39
我不知道你到底想要做什么样的改变,但这就是我要做的:
$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));https://stackoverflow.com/questions/21729287
复制相似问题