我有一个包含混合文本和html标记的字符串(例如锚点,下划线),例如:
$string = 'text1<a href="">text2</a> text3';
我想用span标签包装text1,text2和text3。
这需要精确完成,以便原始的html标签不会制动。即最终结果应该是:
$new_string = '<span>text1</span><a href=""><span>text2</span></a><span>text3</span>';
任何想法如何做到这一点?
答案 0 :(得分:0)
刚刚找到一线解决方案:
JS:
function addSpans($string){
str.replace(/[^<>]+(?=<[^<>]+>)|[^<>]+$/g, (text) => {return "<span>"+text+"</span>";})
}
PHP:
function addSpans($input){
return preg_replace("/[^<>]+(?=<[^<>]+>)|[^<>]+$/","<span>$0</span>",$input);
}
工作原理:
[^<>]+(?=<[^<>]+>)|[^<>]+$
匹配符合[^<>]+(?=<[^<>]+>)
或匹配[^<>]+$
[^<>]+(?=<[^<>]+>)
:任何字符串后跟html标记
[^<>]+
匹配一个或多个不是&lt;或&gt;
(?=<[^<>]+>)
匹配&lt;后跟一个或多个不是&lt;或者&gt;接着是&gt;。这匹配任何html标记
[^<>]+$
:输入结尾处带有html标记的任何字符串
[^<>]+$
与[^<>]+
相同,但在输入结尾处
要在JS中添加span标记,您必须传递一个函数,它将匹配的字符串作为输入,作为替换。
在PHP中,您可以使用$ 0-99在替换中引用匹配的字符串,其中$ 0是与整个模式匹配的字符串。
使用正则表达式无法找到使用单行执行此操作的方法,但此功能应该可以正常工作。
JS代码:
function addSpans($string){
text = $string.split(/<[^>]+>/g);
tags = $string.match(/<[^>]+>/g);
retvar = "";
for(i = 0; i < text.length;i++){
if(typeof text[i] !== 'undefined' && text[i].length > 0){
retvar += "<span>"+text[i]+"</span>";
}
if(typeof tags[i] !== 'undefined'){
retvar += tags[i];
}
}
return retvar;
}
PHP代码:
function addSpans($input){
$text = preg_split('/<[^>]+>/',$input);
$tags = array();
preg_match_all('/<[^>]+>/',$input,$tags);
$retvar = "";
for($i = 0; $i < count($text);$i++){
if(isset($text[$i]) && strlen($text[$i]) > 0){
$retvar .= "<span>".$text[$i]."</span>";
}
if(isset($tags[0][$i])){
$retvar .= $tags[0][$i];
}
}
return $retvar;
}
代码的工作原理如下:
1:按HTML标记拆分字符串
正则表达式如何运作:
<
匹配字符&lt; (打开html标签)
[^>]+
匹配一个或多个不是&gt;的字符。 (关闭html标签)
>
匹配字符&gt; (关闭html标签)
2 .:获取HTML标记。相同的正则表达式,但现在用于匹配而不是拆分
3:在循环中:
3.1:如果当前文本不为空(如果输入以标签开头/结尾),则使用span标签包围当前文本
3.2:添加再次用于拆分的HTML标记。
3.3:使用下一个文本和下一个html标记重新开始。
4:最终返回组合字符串。
我还检查两个代码中是否存在当前文本/标记,以防它们长度不等。