js正則匹配多行文本


原文:https://lwebapp.com/zh/post/regular-expression-to-match-multiple-lines-of-text

需求

最近有小伙伴提了個需求,想用正則表達式從一段 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;
+ }

我們把需求轉換下,就是正則匹配多行文本中以 +- 開頭的行。

解法一

思路:

  1. 首先匹配 + 開頭的字符:\+.*
  2. 然后帶上 -(\+|\-).*
  3. 因為多行文本之間是有換行符分割的,所以 + 開頭的單行文本的前面一個字符,就是上一行最后的換行符 \n,同樣的,這一行的結尾也是換行符。所以我們利用正則斷言,將兩個換行符匹配目標文本的首尾即可:(?<=\n)(\+|\-).*(?=\n)
  4. 最后還要考慮兩個特殊情況,整個文本的首尾位置。首位沒有上一行所以匹配不到換行符 \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

參考


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM