我的正则表达式没有正确替换
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)
我发现我可以使用每个组的引用将该组插入到替换中,所以我没有丢失 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();
使用 DOM
和 XPath
的优点是您可以可靠地访问任何嵌套级别中的样式属性,即使 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 解析器来完成这项工作。
我有这个正则表达式:/(?:(?<=(?: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)
我发现我可以使用每个组的引用将该组插入到替换中,所以我没有丢失 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();
使用 DOM
和 XPath
的优点是您可以可靠地访问任何嵌套级别中的样式属性,即使 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 解析器来完成这项工作。