2017-12-07 18 views
0

私は現在ポスト・コミット・フックとして縮小タスクを進めています。私は現在のバージョンのyui-compressorを使用してCSSを縮小しています。css minificationを修正するためのsed正規表現

yui-compressorの現在のバージョンに関する悪い点: 正しく機能するには空白を必要とする特定のCSS3ルールが壊れます。 (calc(10px + 10px))

問題を修正するために、圧縮後にcalc(...)をすべて置き換える正規表現を書きました。

私の解決策は、これまでのところ、次の正規表現です:置き換え/calc\((.*?)([\/\+\-\*])(.*?)\)/g

calc(\1 \2 \3)

私は正規表現を検証するために2つのオンラインツールを使用し:

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を(前の正規表現に置き換え)は、正規表現の後に:(と正しい結果)

sed -r "s/calc\((.*?)([\/\+\-\*])(.*?)\)/calc(\1 \2 \3)/g" style.css 
:(ファイルから同じルールをロード) - Debianの8のsed

.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)} 

次のように出力されます

.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で動作するようには思えません。誰もが一体何が起こっている手がかりを持っていますか?

ありがとうございます!

答えて

0

PCREの非欲張り反復.*?を使用しようとしていますが、sedPOSIX BRE and EREのみをサポートしていますが、これらは貪欲でない拡張子を定義していません。

代わりに、正規表現を変更する必要があります。あなたの場合、最初に取得したグループ(左側のオペランド)には[^-+*/]*を使用できます。演算子までのすべての値を一致させるには、[^)]*を2番目のオペランドと一致させる必要があります。これは、あなたが期待する出力を生成します:

sed -E 's/calc\(([^-+*/]*)([-+*/])([^)]*)\)/calc(\1 \2 \3)/g' style.css 
#    ^^^^^^^^ ^^^^^^ ^^^^^ 
#   left operand op right operand 
#   all until op   all until) 

-E-rと同等であるが、非GNU sedでも動作します。また、括弧内の演算子をエスケープする必要はありません。実際には、最初の文字として指定されていない場合は閉じ括弧を除いて、括弧の中にエスケープする必要はほとんどありません。最初の文字として指定されている場合は^です。

あなたは.*?は、貪欲.*として扱わ0回以上(?)が繰り返される注意したときに取得された出力は、説明するのは簡単です - 2番目に最初の.*?が行の最後のオペレータまで、すべてのものをキャプチャし、 .*?は最後のオペランドを取得するため、各行の最後のcalc式だけを「展開」します。

+0

チャームのように機能します。どうもありがとう。私はsedが "原始的"であることに気づいていませんでした。 –

+0

ようこそ。実際、 'sed'はsubstitute(' s'コマンド)よりもはるかに多くを行うことができます。これには分岐とループの構造があります。非常に強力な、事実として。 :)残念ながら、PCREはサポートされていませんが、必要があればPerlを試してみてください。 – randomir