翻譯 做CSS精簡時可能會用到的正規表示式

2022-01-31 19:03:21 字數 3143 閱讀 2427

原文:

注意:本文提到的正規表示式都使用了ignorecase=true選項。

我觀察了yui compressor中用於精簡css的正規表示式,並給出了一些我認為能有助於這一工作的其他正規表示式。

我所看到的**已經能夠通過簡單的字串替換修剪掉「上-右-下-左」值中不必要的零值。但這是通過三個獨立的替換操作完成的。如果能用正規表示式處理這種情況,**將會變得更簡單。

(偽**)

string.replace(":0 0 0 0;","0;")

string.replace(":0 0 0;","0;")

string.replace(":0 0;","0;")

可以變為:

regex.replace(input,":("s*0)("s+0)"s*;",":0;")

夠簡單了吧。但我想,怎麼能就此停滯不前呢?於是我給出了可以處理所有數值的正規表示式:

:"s*(0|(?:(?:"d*".?"d+(?:p(?:[xct])|(?:[cem])m|%|in|ex))))("s+"1);

)用於進行替換的字串很簡單:「:$1」。

這一步完成後,下面就是處理各個數值並不全為0的情形。

如果您不大了解css,這裡簡單說一下,此處可能出現4個值:

1)如果只指定乙個值,則另外三個值也都隱式地指定為相同的值(x = x x x);

2)如果指定了二個值,則第三個值和第乙個相等,第四個值和第二個相等(x y = x y x y);

3)如果指定了三個值,則第四個值等於第二個值(x y z = x y z y)。

當然,在精簡時您肯定希望用更短的語法。下面的正規表示式可以使其變短。所有這些情況使用的替換字串都和前面一樣,是「:$1」。

將4個引數替換為2個(x y x y變為x y)

:"s*((0|(?:(?:"d?".?"d(?:p(?:[xct])|(?:[cem])m|%|in|ex))))"s+(0|(?:(?:"d?".?"d(?:p(?:[xct])|(?:[cem])m|%|in|ex)))))"s+"2"s+"3;

)4個變為3個(x y z y變為x y z)或3個變為2個(x y x變為x y)

:"s*((?:(?:0|(?:(?:"d?".?"d(?:p(?:[xct])|(?:[cem])m|%|in|ex))))"s+)?(0|(?:(?:"d?".?"d(?:p(?:[xct])|(?:[cem])m|%|in|ex))))"s+(?:0|(?:(?:"d?".?"d(?:p(?:[xct])|(?:[cem])m|%|in|ex)))))"s+"2;

)較長的這個正規表示式只不過是重複了其中乙個子模式而已。

基於以上這些正規表示式,我提出了類似的模式,用來處理border-style、outline-style、border-color和outline-color。

border-style/outline-style

替換字串為「$1-style:$2;」。

(outline|border)-style"s*:"s*(none|hidden|d(?:otted|ashed|ouble)|solid|groove|ridge|inset|outset )(?:"s+"2);

)(outline|border)-style"s*:"s*((none|hidden|d(?:otted|ashed|ouble)|solid|groove|ridge|inset|outset )"s+(none|hidden|d(?:otted|ashed|ouble)|solid|groove|ridge|inset|outset ))(?:"s+"3)(?:"s+"4);

)(outline|border)-style"s*:"s*((?:(?:none|hidden|d(?:otted|ashed|ouble)|solid|groove|ridge|inset|outset )"s+)?(none|hidden|d(?:otted|ashed|ouble)|solid|groove|ridge|inset|outset )"s+(?:none|hidden|d(?:otted|ashed|ouble)|solid|groove|ridge|inset|outset ))(?:"s+"3);

border-color/outline-color

替換字串為「$1-color:$2;」。

(outline|border)-color"s*:"s*((?:"#(?:[0-9a-f]))|"s+)(?:"s+"2);

)(outline|border)-color"s*:"s*(((?:"#(?:[0-9a-f]))|"s+)"s+((?:"#(?:[0-9a-f]))|"s+))(?:"s+"3)(?:"s+"4);

)(outline|border)-color"s*:"s*((?:(?:(?:"#(?:[0-9a-f]))|"s+)"s+)?((?:"#(?:[0-9a-f]))|"s+)"s+(?:(?:"#(?:[0-9a-f]))|"s+))(?:"s+"3);

)我還給出了其他一些用於替換**的正規表示式,但由於它們都使用了反相匹配,所以移植性會有問題。

這個模式:

"s+((?:[!{};>+()"],])|(?<=]*):(?=[^}]*}))

)用於匹配字元前面不必要的空白字元。要小心偽選擇器和偽類前面的冒號。替換字串為「$1」。

這個模式:

(?)用於精簡16進製制顏色值,將aabbcc變為abc。替換字串為「$1$2$3」。

我還寫了乙個用於匹配形如「rgb(x,y,z)」的rgb值的正規表示式,其中的x、y、z都在0-255之間。

rgb"s*"x28((?:25[0-5])|(?:2[0-4]"d)|(?:[01]?"d?"d))"s*,"s*((?:25[0-5])|(?:2[0-4]"d)|(?:[01]?"d?"d))"s*,"s*((?:25[0-5])|(?:2[0-4]"d)|(?:[01]?"d?"d))"s*"x29

)這個模式僅用於匹配現有**,並將每個數值放到乙個組中,以便進行進一步處理。可以使用matchevaluator遍歷每乙個匹配並完成10進製到16進製制的轉換。

我自己進行了一些alpha測試,但我寫的css根本不能用作測試材料,所以乾脆給大家進行beta測試。我並不是很懂css hack,因此我不知道這些精簡會不會對css hack產生負面影響。我還會將這些資訊告訴yui compressor的維護者,看看他們能不能採納。

遊戲開發中可能會用到的公式

向量 三角不等式 u v u v 柯西不等式 u v u v 標量三重積 u v w w u v v w u 向量三重積 u v w u w v u v w 矩陣 矩陣的跡是方陣主對角線元素之和,可以表示為tr m 如果一組基向量的行列式為正,那麼它可以構成乙個右手座標系,也稱正向基。如果為負,那麼...

Python你可能會用到的時間比較

最近用python來做時間的比較,整理一下。場景 資料庫儲存的是datetime.datetime.now 的str型別的資料,需要把資料庫儲存的時間跟現在的時間進行比較。用到的庫 datetime.datetime.now datetime.datetime.strptime datetime.t...

HTML可能會用到的一些知識

doctype宣告一般位於文件的第一行,它的作用主要是告訴瀏覽器以什麼樣的模式來解析文件。一般指定了之後會以標準模式來解析文件,否則不指定就以相容模式來解析。html5為什麼系需要引入 而不需要引入dtd?常見的空元素有哪些?meta viewport 是做什麼的?怎麼寫?頁面匯入樣式時,使用 li...