我目前正在处理一个缩小任务作为提交后的钩子。我正在使用当前版本的yui压缩器进行CSS缩小。
当前版本的yui-compressor的坏处: 它破坏了某些需要空格才能正常运行的 CSS3 规则。(计算(10px + 10px))
为了解决这个问题,我写了一个正则表达式,应该替换压缩后每次出现的 calc(...)。
到目前为止,我的解决方案是以下正则表达式:
匹配:/calc((.*?)([/+-*])(.*?))/g
替换:calc(1 2 3)
我使用了两个在线工具来验证我的正则表达式:
https://regex101.com/
https://regexr.com/
它也适用于PHP。但是一旦我使用"sed",每行的最后一个出现次数就会被替换:
压缩 CSS:(替换为正则表达式之前)
.test{width:calc(1px+1px)}.test2{left:calc(4%+140px)}.test3{width:calc(1px+1px)}
.test{width:calc(1px-1px)}.test2{left:calc(4%-140px)}.test3{width:calc(1px-1px)}
.test{width:calc(1px*1px)}.test2{left:calc(4%*140px)}.test3{width:calc(1px*1px)}
.test{width:calc(1px/1px)}.test2{left:calc(4%/140px)}.test3{width:calc(1px/1px)}
正则表达式后的 CSS:(和正确的结果)
.test{width:calc(1px + 1px)}.test2{left:calc(4% + 140px)}.test3{width:calc(1px + 1px)}
.test{width:calc(1px - 1px)}.test2{left:calc(4% - 140px)}.test3{width:calc(1px - 1px)}
.test{width:calc(1px * 1px)}.test2{left:calc(4% * 140px)}.test3{width:calc(1px * 1px)}
.test{width:calc(1px / 1px)}.test2{left:calc(4% / 140px)}.test3{width:calc(1px / 1px)}
Debian 8 中的 sed - (从文件加载相同的规则):
sed -r "s/calc((.*?)([/+-*])(.*?))/calc(1 2 3)/g" style.css
打印以下内容:
.test{width:calc(1px+1px)}.test2{left:calc(4%+140px)}.test3{width:calc(1px + 1px)}
.test{width:calc(1px-1px)}.test2{left:calc(4%-140px)}.test3{width:calc(1px-1px)}
.test{width:calc(1px*1px)}.test2{left:calc(4%*140px)}.test3{width:calc(1px * 1px)}
.test{width:calc(1px/1px)}.test2{left:calc(4%/140px)}.test3{width:calc(1px / 1px)}
它似乎不适用于 sed。有谁知道到底发生了什么?
提前感谢!
您正在尝试使用 PCRE 非贪婪重复.*?
,但sed
仅支持 POSIX BRE 和 ERE,它们没有定义非贪婪扩展。
相反,您必须修改正则表达式。在您的情况下,您可以将[^-+*/]*
用于第一个捕获的组(左操作数)——匹配运算符之前的所有内容,[^)]*
匹配第二个操作数——直到右括号的所有内容。这将产生您期望的输出:
sed -E 's/calc(([^-+*/]*)([-+*/])([^)]*))/calc(1 2 3)/g' style.css
# ^^^^^^^^ ^^^^^^ ^^^^^
# left operand op right operand
# all until op all until )
注意-E
等同于-r
,但也可以在非GNUsed
中使用。此外,您无需在括号内转义运算符。事实上,括号内几乎不需要转义任何东西 - 除了右括号(如果未作为第一个字符提供)和^
如果作为第一个字符提供。
当你注意到.*?
被视为贪婪.*
,重复零次或多次(?
)时,你得到的输出很容易解释 - 第一个.*?
捕获所有内容,直到行中的最后一个运算符,第二个.*?
将捕获最后一个操作数,因此仅"扩展"每行中的最后一个calc
表达式。