我需要将字符串This <span style="font-size: 16px;" style="color: red;">is</span> a test.
转换为This <span style="font-size: 16px; color: red;">is</span> a test.
也有可能有两个以上的匹配,或者可能有style
,然后是class
,然后是另一个style
和style
s需要合并。它们并不总是span
s
不幸的是,Tidy不是一个选项,因为它的清洁工作比这个项目更容易承受。
由于多个样式属性无效,因此转到DOM文档路由将不起作用,因此它只获取第一个样式的内容。
我想用preg_replace来做,但是从一个标签中获取匹配证明是非常困难的。
如果它使事情变得更容易,它们就像嵌套标签一样开始。我有一个preg_replace,它从那里组合它们并给出这个输出。
答案 0 :(得分:0)
我同意上面的评论,最好的解决方案是首先防止这种情况,但回答你的问题:这个函数将结合给定字符串中的所有样式属性。只需确保一次只传递一个标签。标签中有多少其他属性并不重要,订单也不重要。它会将所有样式属性组合到第一个样式值中,然后删除所有其他样式属性:
/**
* @param string $str
* @return string
*/
function combineStyles($str)
{
$found = preg_match_all("/style=\"([^\"]+)\"/", $str, $matches);
if ($found)
{
$combined = 'style="' . implode(';', $matches[1]) . '"';
$patterns = $matches[0];
$replace = array_pad(array($combined), count($matches[0]), '');
$str = str_replace($patterns, $replace, $str);
}
return $str;
}
答案 1 :(得分:0)
等等,我刚刚意识到它不能与style="" id="" style=""
合作。
<?php
$str = 'This <span style="font-size: 16px" style="color: red;">is</span> a test. This <span style="font-size: 16px;" style="color: red;">is</span> a test.';
while (preg_match('/"\s+style="/', $str, $matches))
{
$pos = strpos($str, $matches[0]);
$prev = substr($str, 0, $pos);
if (substr(trim($prev), -1) != ";")
$prev .= ";";
$str = $prev.substr($str, $pos+strlen($matches[0]));
}
?>
答案 2 :(得分:0)
在Visual Studio 2012的快速替换中使用.Net正则表达式,这个表达式对我有用:
Find:
style\s*=\s*(?<q2>['"])(?<w1>(?:(?!\k<q2>).)*?);?\k<q2>\s*(?<c>[^<>]*)\s*style\s*=\s*(?<q2>['"])(?<w2>(?:(?!\k<q2>).)*?);?\k<q2>
Replace:
style="${w1};${w2};" ${c}
注意:
1.这一次只会合并两个style
属性。如果单个标记中有多个标记,则需要多次运行。
2.两个样式属性之间的任何内容都将放在第一个样式属性之后(这将是放置合并样式属性的位置)
解释
Find:
style # match a style attribute
\s* # match any optional white space
= # match equals sign
\* # match any optional white space
(?<q2>['"]) # match either a single or double quote and stored in named capture 'q'
(?<w1> # start capture of first style attribute's content
(?: # start non-capturing match
(?!\k<q2>) # negative look-ahead to prevent matching on this attribute's quote
.)*? # end non-capturing match with minimal, 0-many quantifier
) # end capture of first style attribute's content
;? # place trailing semi-colon (if present) outside the capture
\k<q2> # match closing quote
\s* # match white space
(?<c>[^<>]*) # capture content between style attributes
\s* # match white space
... # repeat the above for a second style attribute
# except that the second style's capture is named 'w2'
Replacement:
style=" # start merged style attribute
${w1}; # place first style attribute's content
${w2}; # place second style attribute's content
" # finish merge style attribute
${c} # restore any content found between the two style attributes