我的正则表达式没有正确替换

My regex is not replacing correctly

我有这个正则表达式:/(?:(?<=(?:style=["])).*)(line-height.*?)[;"]/i

$regex = '/(?:(?<=(?:style=["])).*)(line-height.*?)[;"]/i';

preg_replace("/(?:(?<=(?:style=[\"'])).*)(line-height.*?)[;\"]/i", "HELLO", $input);

这是输入:

    <li><span style="line-height: 20.14399986267089px">500.00dkk</span></li>
<li style="color:red; line-height: 21.14399986267089px"></li>

我只想用 HELLO 替换 "line-height: SOMENUMBERpx" 的出现(它还必须以样式标签开头): 但我无法使其正常工作。现在它取代了行高属性,但它也取代了:color:red,这是我不想要的。

这是我想要的输出:

<li><span style=HELLO>500.00dkk</span></li> 
<li style="color:red; HELLO"></li>

谁能看出我做错了什么?

这就是你想要的正则表达式

(line-height:\s+\d+\.\d+px)

Debuggex Demo

我发现我可以使用每个组的引用将该组插入到替换中,所以我没有丢失 color:red 部分。

preg_replace ('/(?<=style=["])(.*)(line-height.*?)[;"]/', 'HELLO', $input);

这给了我想要的结果。

这里可以使用\K\K resets the starting point of the reported match. Any previously consumed characters are no longer included in the final match

style=.*?\Kline-height.*?(?=[;"])

试试这个。See demo.

这将确保只有 line=height... 会被替换,并且它前面还有 style=

我会使用 DOM 解析器来提取样式属性并使用 preg_replace():

修改内容
$input = <<<EOF
<li><span style="line-height: 20.14399986267089px">500.00dkk</span></li>
<li style="color:red; line-height: 21.14399986267089px"></li>
EOF;

# Create a document from input
$doc = new DOMDocument();
$doc->loadHTML($input);

# Create an XPath selector
$selector = new DOMXPath($doc);

# Modify values of the style attributes
foreach($selector->query('//@style') as $style) {
    $style->nodeValue = preg_replace(
        '/line-height:\s*[0-9]+(\.[0-9]+)?px\s*;?/',
        'HELLO;',
        $style->nodeValue
    );
}

# Output the modified document
echo $doc->saveHTML();

使用 DOMXPath 的优点是您可以可靠地访问任何嵌套级别中的样式属性,即使 HTML 内容变得异常。如果 HTML 结构在未来发生变化,或者如果你想更接近地指定哪些样式属性应该改变,也很容易维护。

以下面的查询为例,它仅选择具有 class even 并且是 [=19 的子级(在任何嵌套级别)的 <span> 标签的样式属性=] 与 id="foo".

//div[@id="foo"]//span[contains(@class, "even")]/@style

如果你用正则表达式试试这个,你会得到很多乐趣! :)


关于 CSS 部分。我决定为此使用正则表达式,因为我能想到的唯一可以破坏正则表达式的东西是:

<span style="background:url('line-height:2px');">

因为 line-height:2px 是一个有效的 UNIX 文件名,上面的内容是可能的。但是,嘿! :) 如果您真的很在意,您需要使用 CSS 解析器来完成这项工作。