用 Excel 處理資料時,有時需要對字元串進行拆分。對于比較簡單的拆分,使用 Excel 函數可以順利完成,但碰到一些特殊需求,或者拆分的規則比較複雜時,則很難用 Excel 實作了。這裡列出一些拆分需求示例,分析拆分難點,并提供 SPL 解決代碼。SPL 是專業計算引擎 esProc 使用的語言,用于處理結構化資料運算非常友善,對于字元串拆分的運算也很簡單。
一、規則單詞拆分
這裡有一份工廠中的房間采購産品清單,清單的每一項包含了需要采購的品牌以及産品型号。現在想要把每一項的品牌以及型号拆分後單獨列到後面。
檔案 productlist.xlsx 中資料如下:

期望結果:
使用 Excel 來處理這類拆分時,可以使用資料的分列,但是分列有個缺點,其實也算不上缺點,隻是針對這個隻想拆出品牌的需求來說單詞被過渡拆分了。比如後面的型号,也會被拆分到多個列,又需要重新合并,過程有點得不償失。不過 Excel 還有一個快速填充,可以根據給定的參考值,比如第一行給定 PANASONIC,便可使用類似規則快速填充後面行的拆分,然後再用 Mid 函數間接算出型号的字元串部分,過程依然繁瑣。
使用 SPL 可以直接讀取 Excel 檔案,對于實時分析操作,也可以将 Excel 中的資料複制到剪貼闆,然後在 SPL 裡面使用 clipboard 函數直接從剪貼闆擷取資料,資料整理完後,再将結果放入剪貼闆,然後在 Excel 中粘貼結果,這樣便可将 Excel 的分析操作跟 SPL 的計算無縫對接起來,友善而又高效。
SPL 拆分代碼:
A | B | |
1 | =clipboard()[email protected]() | /從剪貼闆導入産品清單 |
2 | =A1.([email protected](" ")) | /從第一個空格處将産品清單分離為兩部分,産生一個序列的序列 |
3 | [email protected]("t") | /拼接為子序列的成員用 Tab 分隔,序列的成員之間用回車分隔的二維表串 |
4 | =clipboard(A3) | /将串值放置到剪貼闆 |
代碼執行完成後,隻需在B1 格粘貼便可得到期望結果。
二、數字分離
如下為一些數字跟字元混合在一起的資料,現在需要将數字和字元分離開。
檔案 numbers.xlsx 中資料如下:
期望結果:
如果是光分離數字出來,仍然可以使用給定首行參考值,然後采用快速填充,便可以将所有數字分離出來。但是要将剩餘的字元再分離出來,Excel 沒有合适的辦法,因為有些數字是跟字元交叉混合在一起,沒法用 Mid 等函數拆分。隻能采用 VBA 寫代碼逐字循環,判斷字元類型,挨個分離,過程依然麻煩。
SPL 可以直接将串分離成單字元,并根據類型劃分:
A | B | |
1 | =clipboard()[email protected]() | /将剪貼闆資料按回車拆分為成員,然後将成員再逐字拆分 |
2 | =A1.([email protected]([true,false],isdigit(~)).(~.concat())) | /每一項字元序列用是否為數字分成兩組,繼而再拼成串,進而分離出數字和字元 |
3 | [email protected]("t") | /将兩層序列分别用 Tab 和回車拼為二維表式的大串 |
4 | =clipboard(A3) | /将大串放置到剪貼闆 |
三、日期分離
下面為一些包含日期的句子或段落,現在想要把句子裡面所有的日期分離出來,一行中包含多個日期時,用分号分開。
檔案 multidates.xlsx 中資料如下:
期望結果:
要将句子裡面的日期分離出來,Excel 沒有相應的辦法,尤其像這種一個句子裡面有不定個數的日期。如果是固定位置或長度的日期格式,才可能用截取固定長度,或者使用快速填充能夠辦到。對于上述多個日期的分離,隻能寫 VBA 代碼,再用正規表達式去比對解析,完成這種需求對人員要求較高,且實作過程繁瑣。
SPL 直接用空格分割串為單詞序列,然後按格式轉換日期類型的資料:
A | B | |
1 | =clipboard()[email protected](“ “) | /将剪貼闆資料按回車拆分成員,然後用空格将每一成員拆分為單詞序列 |
2 | =A1.(~. (date(~,"dd.MM.yy"))) | /将單詞序列的成員按照指定格式轉換為日期類型的資料 |
3 | =A2.(~.select(ifdate(~))) | /選出序列中的日期類型的值 |
4 | =clipboard([email protected](“;”)) | /将日期串序列結果拼接為二維表串并放置到剪貼闆 |
執行完上述代碼後,直接在源表中的B1 格執行粘貼,即可得到期望結果。
四、按字元拆分
如下表為一列長度不等的數字,現在需要将數字逐字拆分成為單獨的列。
檔案 number.xlsx 的資料:
期望結果:
使用 Excel 拆分上述數字時,首先想到的是使用分列,但是像這種逐字拆分,分列時隻能一個一個指定分隔位,數字比較長時就要多次重複設定,操作多而麻煩。其次是使用函數,比如可以在 B1 寫入 =MID($A1,COLUMN(A1),1),然後拖拽滑鼠進行行填充以及列填充,但這種操作不好掌握最大列數,篇幅大時,操作也不友善。
SPL 可以直接按字元拆分:
A | B | |
1 | =clipboard()[email protected]() | /将剪貼闆資料按回車拆分成員,然後每個成員再預設拆分為單字元序列 |
2 | [email protected]("t") | /将拆分後的兩層序列拼成串式二維表 |
3 | =clipboard(A2) | /将結果放置到剪貼闆 |
上述代碼執行完成後,同樣在 B1 處粘貼拆分後的資料即可。
五、屬性表和檔案名拆分
如下資料為一段日志描述檔案,結構相對複雜,其中包含類似于屬性表的分節描述。現在想将屬性描述中的 PublicKeyToken 以及檔案名分離出來。
檔案 log.xlsx 的資料:
期望結果:
這是一個綜合串的分離,第一層為用逗号分隔的描述串,然後第二項類似于屬性分節串的描述。是以使用 Excel 時,需要多次分列,以及多次快速填充,方可完成期望結果。同樣是步驟多,且需要給定參考值來快速填充,過程繁瑣。
SPL 提供了函數直接對屬性串取值,以及對檔案名的不同部分拆分:
A | B | |
1 | =clipboard()[email protected]() | /将剪貼闆資料用回車拆分成員,然後以逗号拆分子成員序列 |
2 | =A1.([replace(~(2),""","").property("PublicKeyToken"),filename(replace(~(3),""",""))]) | /去掉兩端引号後,用屬性 property 函數從第 2 項擷取 PublicKeyToken 的值;再用 filename 函數拆分出第 3 項中的檔案名;再将這兩個值構成序列 |
3 | =clipboard([email protected]("t")) | /将結果拼為大串放置到剪貼闆 |