sed 正则表达式修复 css 缩小
sed regular expression to fix css minification
我目前正在作为 post 提交挂钩处理缩小任务。我正在使用当前版本的 yui-compressor 进行 CSS-minification.
当前版本的 yui-compressor 的缺点:
它打破了某些需要空格才能正常运行的 CSS3 规则。 (计算(10px + 10px))
为了解决这个问题,我写了一个正则表达式,它应该在压缩后替换每次出现的 calc(...)。
我目前的解决方案是以下正则表达式:
匹配:/calc\((.*?)([\/\+\-\*])(.*?)\)/g
替换:calc( )
我使用了两个在线工具来验证我的正则表达式:
它也适用于 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( )/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 and ERE,未定义非贪婪扩展。
相反,您必须修改您的正则表达式。在您的情况下,您可以对第一个捕获的组(左操作数)使用 [^-+*/]*
- 匹配运算符之前的所有内容,并使用 [^)]*
匹配第二个操作数 - 直到右括号的所有内容。这将产生您期望的输出:
sed -E 's/calc\(([^-+*/]*)([-+*/])([^)]*)\)/calc( )/g' style.css
# ^^^^^^^^ ^^^^^^ ^^^^^
# left operand op right operand
# all until op all until )
注意 -E
等同于 -r
,但也适用于非 GNU sed
。此外,您不需要在括号内转义运算符。事实上,括号内几乎没有任何内容需要转义——除了右括号(如果没有作为第一个字符提供)和 ^
(如果作为第一个字符提供)。
当您注意到 .*?
被视为贪婪的 .*
,重复零次或多次 (?
) 时,您得到的输出很容易解释 - 第一个.*?
捕获行中最后一个运算符之前的所有内容,第二个 .*?
将捕获最后一个操作数,因此 "expanding" 仅捕获每行中的最后一个 calc
表达式。
我目前正在作为 post 提交挂钩处理缩小任务。我正在使用当前版本的 yui-compressor 进行 CSS-minification.
当前版本的 yui-compressor 的缺点: 它打破了某些需要空格才能正常运行的 CSS3 规则。 (计算(10px + 10px))
为了解决这个问题,我写了一个正则表达式,它应该在压缩后替换每次出现的 calc(...)。
我目前的解决方案是以下正则表达式:
匹配:/calc\((.*?)([\/\+\-\*])(.*?)\)/g
替换:calc( )
我使用了两个在线工具来验证我的正则表达式:
它也适用于 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( )/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 and ERE,未定义非贪婪扩展。
相反,您必须修改您的正则表达式。在您的情况下,您可以对第一个捕获的组(左操作数)使用 [^-+*/]*
- 匹配运算符之前的所有内容,并使用 [^)]*
匹配第二个操作数 - 直到右括号的所有内容。这将产生您期望的输出:
sed -E 's/calc\(([^-+*/]*)([-+*/])([^)]*)\)/calc( )/g' style.css
# ^^^^^^^^ ^^^^^^ ^^^^^
# left operand op right operand
# all until op all until )
注意 -E
等同于 -r
,但也适用于非 GNU sed
。此外,您不需要在括号内转义运算符。事实上,括号内几乎没有任何内容需要转义——除了右括号(如果没有作为第一个字符提供)和 ^
(如果作为第一个字符提供)。
当您注意到 .*?
被视为贪婪的 .*
,重复零次或多次 (?
) 时,您得到的输出很容易解释 - 第一个.*?
捕获行中最后一个运算符之前的所有内容,第二个 .*?
将捕获最后一个操作数,因此 "expanding" 仅捕获每行中的最后一个 calc
表达式。