原文:https://lwebapp.com/zh/post/r...
需求
最近有小夥伴提了個需求,想用正規表示式從一段 git 提交記錄中提取出具體更新了哪些程式碼,簡單來說就是 commit diff 展示的程式碼,需要把 程式碼前面帶 +
和 -
的行剝離出來。
我們從 RichX 專案複製出來一段提交記錄,稍作修改用於演示。
+ import { Plugin } from "..";
- CONST SUM = NUM_A + NUM_B;
+ CONST SUM_ALL = NUM_A + NUM_B;
export const DEFAULT_RICH_TEXT = {
- text: "Simple Rich Text Demo",
+ config: "Simple Rich Text Demo",
setting: [],
};
export type ObjectKV<V = object> = {
[key: string]: V;
};
+ export interface IPlugins {
+ [key: string]: Plugin;
+ }
我們把需求轉換下,就是正則匹配多行文字中以 +
和 -
開頭的行。
解法一
思路:
- 首先匹配
+
開頭的字元:\+.*
- 然後帶上
-
:(\+|\-).*
- 因為多行文字之間是有換行符分割的,所以
+
開頭的單行文字的前面一個字元,就是上一行最後的換行符\n
,同樣的,這一行的結尾也是換行符。所以我們利用正則斷言,將兩個換行符匹配目標文字的首尾即可:(?<=\n)(\+|\-).*(?=\n)
- 最後還要考慮兩個特殊情況,整個文字的首尾位置。首位沒有上一行所以匹配不到換行符
\n
,只能匹配開頭^
,結尾後面也可能沒有換行符,用$
代替:(?<=^|\n)(\+|\-).*(?=\n|$)
程式碼:
const content = `+ import { Plugin } from "..";
- CONST SUM = NUM_A + NUM_B;
+ CONST SUM_ALL = NUM_A + NUM_B;
export const DEFAULT_RICH_TEXT = {
- text: "Simple Rich Text Demo",
+ config: "Simple Rich Text Demo",
setting: [],
};
export type ObjectKV<V = object> = {
[key: string]: V;
};
+ export interface IPlugins {
+ [key: string]: Plugin;
+ }`
content.match(/(?<=^|\n)(\+|\-).*(?=\n|$)/g)
// 輸出陣列
// 0: "+ import { Plugin } from \"..\";"
// 1: "- CONST SUM = NUM_A + NUM_B;"
// 2: "+ CONST SUM_ALL = NUM_A + NUM_B;"
// 3: "- text: \"Simple Rich Text Demo\","
// 4: "+ config: \"Simple Rich Text Demo\","
// 5: "+ export interface IPlugins {"
// 6: "+ [key: string]: Plugin;"
// 7: "+ }"
解法二
思路:
上面的方案要自己匹配換行符,有點麻煩。我們可以省去自己判斷換行符的步驟,直接匹配每一行的首尾,再使用正規表示式標誌 m
啟用多行匹配模式:/^(\+|\-).*$/gm
。
程式碼:
const content = `+ import { Plugin } from "..";
- CONST SUM = NUM_A + NUM_B;
+ CONST SUM_ALL = NUM_A + NUM_B;
export const DEFAULT_RICH_TEXT = {
- text: "Simple Rich Text Demo",
+ config: "Simple Rich Text Demo",
setting: [],
};
export type ObjectKV<V = object> = {
[key: string]: V;
};
+ export interface IPlugins {
+ [key: string]: Plugin;
+ }`
content.match(/^(\+|\-).*$/gm)
// 輸出陣列
// 0: "+ import { Plugin } from \"..\";"
// 1: "- CONST SUM = NUM_A + NUM_B;"
// 2: "+ CONST SUM_ALL = NUM_A + NUM_B;"
// 3: "- text: \"Simple Rich Text Demo\","
// 4: "+ config: \"Simple Rich Text Demo\","
// 5: "+ export interface IPlugins {"
// 6: "+ [key: string]: Plugin;"
// 7: "+ }"
總結
以上就是和小夥伴一起探討出的一點寫正規表示式的經驗,主要學習了斷言和多行匹配標誌。這裡的案例還比較簡單,後續有更深入使用案例再和大家分享,歡迎關注我們的更新 #regex。