简体   繁体   English

PHP使用正则表达式更改HTML字符串中的CSS属性

[英]PHP Using Regular Expressions to change css propertyin html string

I have html eg below and would like to use regular expressions to change the font-size on the fly. 我下面有html,例如,我想使用正则表达式即时更改字体大小。

<p><span style="font-size: small;"><img style="float: left;padding:5px" title="Ikechukwu to host Lagos Smirnoff party" src="afrostarpics/586.jpg" alt="Ikechukwu to host Lagos Smirnoff party" width="200" height="300">Smirnoff held a party like never seen before in East, North and West Africa on Friday 23rd September 2011, when they held a “Kick off” party for the Smirnoff Midnight Cruise.&nbsp; The grand party held in the populous West African nation of Nigeria was so successful that it left revellers literally begging for more.</span></p>

this is the regular expression i have 这是我有的正则表达式

    <?php 
$bd=$nobj->body;//html string to change
$selector="font-size"; //selector to change
$property="1.2em"; //new value
 preg_replace('/('.$selector.'\s*\{[\w\s:\-;\(\)#]*)('.$property.'\s*:)([^;\}]+)(;|\})/Ui', '$1 $4', $bd); 
echo $bd;
?>

any ideas as to why this is not working 关于为什么这不起作用的任何想法

If you're set on using regex for this, you'll probably find this pattern more effective: 如果您打算为此使用正则表达式,则可能会发现此模式更有效:

$bd = preg_replace('/\b'.$selector.'\s*:[^;}"\']*/i', $selector.':'.$property, $bd);

That should do what you're trying to do at least 99% of the time. 那应该至少要在99%的时间内完成您想做的事情。

However, I want to point out that you seem to be trying to use regex to parse CSS embedded inside HTML, which is not usually something regex is good at. 但是,我想指出的是,您似乎正在尝试使用正则表达式来解析嵌入在HTML中的CSS,而regex通常不擅长此功能。 Even with this simple task, to solve it in a robust way you would have to distinguish between HTML attribute values and other text, which means you would have to (at least partially) parse the HTML. 即使完成了这个简单的任务,要以健壮的方式解决问题,您也必须区分HTML属性值和其他文本,这意味着您必须(至少部分地)解析HTML。 Doing that with regex is usually a Bad Idea, but it's incredibly simple for jQuery (client-side) or HTML Purifier (server-side). 使用正则表达式执行此操作通常不是一个好主意,但是对于jQuery (客户端)或HTML Purifier (服务器端)而言它非常简单。

Why is regex such a dangerous tool for this? 为什么正则表达式如此危险呢? Well, although the task itself is fairly simple, you probably don't know in advance what the plain-text part is going to say, and regex can't tell the difference between plain text and HTML. 好吧,尽管任务本身非常简单,但是您可能事先不知道纯文本部分要说什么,而regex不能分辨纯文本和HTML之间的区别。 So if the phrase "font-size:" appears in your plain text (meaning the Smirnoff held a party like... part), it will probably break any sane regex. 因此,如果在您的纯文本中出现“ font-size:”一词(意味着Smirnoff held a party like... ),它可能会破坏任何理智的正则表达式。 Unlikely? 不可能? Yes, but it's still a potential bug. 是的,但是它仍然是潜在的错误。

One possible reason is that preg_replace returns the modified string, so you have to save and use the return value - something like this will work if the regex is correct: 一个可能的原因是preg_replace返回修改后的字符串,因此您必须保存并使用返回值-如果正则表达式正确,则类似的事情将起作用:

$bd = preg_replace('/('.$selector.'\s*\{[\w\s:\-;\(\)#]*)('.$property.'\s*:)([^;\}]+)(;|\})/Ui', '$1 $4', $bd);
echo $bd;

Your regular expression looks overly complicated to me. 您的正则表达式对我来说看起来过于复杂。

You could always parse the results as XML, and then modify the attributes, but assuming you still want REGEX, I think something like this should suffice: 您总是可以将结果解析为XML,然后修改属性,但是假设您仍然想要REGEX,我认为这样就可以满足要求:

$old = '<p><span style="font-weight:bold;color:blue;font-size: small;"><img style="float: left;padding:5px" title="Ikechukwu to host Lagos Smirnoff party" src="afrostarpics/586.jpg" alt="Ikechukwu to host Lagos Smirnoff party" width="200" height="300">Smirnoff held a party like never seen before in East, North and West Africa on Friday 23rd September 2011, when they held a “Kick off” party for the Smirnoff Midnight Cruise.&nbsp; The grand party held in the populous West African nation of Nigeria was so successful that it left revellers literally begging for more.</span></p>';
$selector      = 'font-size';
$desired_value = '1\.2em';
$new = preg_replace(
    '/\b(' . $selector . ')\s*:\s*(?!' . $desired_value . ').+\s*([;"\'])/Ui',
    '\1:' . stripslashes($desired_value) . '\2',
    $old
);

For reference, with the values you gave, that gives an output regex of: 作为参考,使用您提供的值,可以得到以下输出正则表达式:

\b(font-size)\s*:\s*(?!1\.2em).+?\s*([;"'])

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM