在 Excel 中使用正則表達式 (RegExp) 解析文本

在 Excel 中使用正則表達式 (RegExp) 解析文本在 Excel 中處理文本時,最耗時和最令人沮喪的任務之一是 解析 – 將字母數字“粥”解析成組件並從中提取我們需要的片段。 例如:

  • 從地址中提取郵政編碼(如果郵政編碼總是在開頭很好,但如果不是呢?)
  • 從銀行對賬單中的付款說明中查找發票編號和日期
  • 從交易對手列表中公司的雜亂無章的描述中提取 TIN
  • 在描述等中搜索車號或貨號。

通常在這種情況下,在手動挑選文本半小時後,腦海中就會開始想辦法以某種方式自動化這個過程(尤其是在有大量數據的情況下)。 有幾種解決方案,並且具有不同程度的複雜性效率:

  • 使用 內置 Excel 文本函數 搜索剪切膠水文本: 左室SIMV (剩下), RIGHT (對), PSTR (中), STEPIT (連接) 及其類似物, 結合 (聯合文本), 精確 (精確的) 等如果文本中有清晰的邏輯(例如索引始終在地址的開頭),則此方法很好。 否則,公式會變得更加複雜,有時甚至會涉及到數組公式,這在大型表上會大大減慢速度。
  • 運用 像文本相似度算子 來自包裝在自定義宏函數中的 Visual Basic。 這允許您使用通配符(*、#、? 等)實現更靈活的搜索。不幸的是,此工具無法從文本中提取所需的子字符串 - 僅檢查它是否包含在其中。

除了上述之外,還有另一種在專業程序員、Web 開發人員和其他技術人員的小圈子中非常知名的方法——這就是 常用表達 (正則表達式 = RegExp = “regexps” = “regulars”)。 簡單的說, RegExp 是一種語言,其中特殊字符和規則用於在文本中搜索必要的子字符串,提取它們或用其他文本替換它們. 正則表達式是一個非常強大和漂亮的工具,它超越了所有其他處理文本的方式一個數量級。 許多編程語言(C#、PHP、Perl、JavaScript……)和文本編輯器(Word、Notepad++……)都支持正則表達式。

不幸的是,Microsoft Excel 沒有開箱即用的 RegExp 支持,但這可以通過 VBA 輕鬆修復。 從選項卡打開 Visual Basic 編輯器 開發人員 (開發商) 或鍵盤快捷鍵 其他+F11. 然後通過菜單插入新模塊 插入 - 模塊 並在那裡複製以下宏函數的文本:

公共函數 RegExpExtract(Text As String, Pattern As String, Optional Item As Integer = 1) As String On Error GoTo ErrHandl Set regex = CreateObject("VBScript.RegExp") regex.Pattern = Pattern regex.Global = True If regex.Test (Text) Then Set matches = regex.Execute(Text) RegExpExtract = matches.Item(Item - 1) Exit Function End If ErrHandl: RegExpExtract = CVErr(xlErrValue) End Function  

我們現在可以關閉 Visual Basic 編輯器並返回 Excel 來試用我們的新功能。 它的語法如下:

=RegExpExtract(文本;模式;項目)

哪裡

  • TXT – 一個包含我們正在檢查的文本的單元格,並且我們想要從中提取我們需要的子字符串
  • 模式 – 子字符串搜索的掩碼(模式)
  • 項目 – 要提取的子串的序號,如果有多個(如果沒有指定,則顯示第一個出現)

當然,這裡最有趣的是 Pattern——RegExp 的“語言中”特殊字符的模板字符串,它指定了我們想要找到的確切內容和位置。 以下是幫助您入門的最基本內容:

 信號模式  產品描述
 . 最簡單的是一個點。 它匹配指定位置的模式中的任何字符。
 s 任何看起來像空格的字符(空格、製表符或換行符)。
 S
先前模式的反變體,即任何非空白字符。
 d
任何數字
 D
前一個的反變體,即任何非數字
 w 任何拉丁字符 (AZ)、數字或下劃線
 W 前一個的反變體,即不是拉丁文,不是數字,也不是下劃線。
[個字] 在方括號中,您可以指定文本中指定位置允許的一個或多個字符。 例如 藝術 將匹配任何單詞: or 椅子.

您也可以不枚舉字符,而是將它們設置為由連字符分隔的範圍,即,而不是 [ABCDEF][自動對焦]. 或者相反 [4567] 介紹 [-4 7]. 例如,要指定所有西里爾字符,您可以使用模板 [a-yaA-YayoYo].

[^個字] 如果在左方括號後添加符號“蓋子” ^,則該集合將獲得相反的含義——在文本中的指定位置,所有字符都將被允許,除了列出的字符。 是的,模板 [^ЖМ]ut 會發現 途徑 or 物質 or 忘記但不 可怕 or MUT,例如。
 | 布爾運算符 OR (要么) 檢查任何指定的標準。 例如 (和週四|s偶數|發票) 將在文本中搜索任何指定的單詞。 通常,一組選項括在括號中。
 ^ 行首
 $ 行結束
 b 詞尾

如果我們正在尋找一定數量的字符,例如,六位數的郵政編碼或所有三字母的產品代碼,那麼我們會來救援 量詞 or 量詞 是指定要搜索的字符數的特殊表達式。 量詞應用於它之前的字符:

  量子  產品描述
 ? 零次或一次出現。 例如 .? 將意味著任何一個字符或它的缺席。
 + 一個或多個條目。 例如 d+ 表示任意位數(即 0 到無窮大之間的任意數)。
 * 零次或多次出現,即任意數量。 所以 s* 表示任意數量的空格或沒有空格。
{} or

{number1,number2}

如果您需要指定嚴格定義的出現次數,則在花括號中指定。 例如 d{6} 嚴格表示六位數,而模式 小號{2,5} – 兩到五個空格

現在讓我們進入最有趣的部分——分析創建函數的應用以及我們從生活中的實際例子中學到的模式。

從文本中提取數字

首先,我們來分析一個簡單的案例——你需要從字母數字粥中提取第一個數字,例如,從價目表中提取不間斷電源的功率:

在 Excel 中使用正則表達式 (RegExp) 解析文本

正則表達式背後的邏輯很簡單: d 表示任何數字,量詞 + 說他們的人數應該是一個或多個。 函數前面的雙減號用於“即時”將提取的字符從數字文本轉換為完整數字。

郵編

乍一看,這裡的一切都很簡單——我們要連續查找六位數字。 我們使用特殊字符 d 用於數字和量詞 6{} 對於字符數:

在 Excel 中使用正則表達式 (RegExp) 解析文本

但是,當行中的索引左側有一大組連續的數字(電話號碼、TIN、銀行賬戶等)時,可能會出現這種情況。那麼我們的常規賽將提取前 6 個來自它的數字,即無法正常工作:

在 Excel 中使用正則表達式 (RegExp) 解析文本

為了防止這種情況發生,我們需要在正則表達式的邊緣添加一個修飾符 b 表示一個詞的結束。 這將使 Excel 清楚我們需要的片段(索引)應該是一個單獨的單詞,而不是另一個片段(電話號碼)的一部分:

在 Excel 中使用正則表達式 (RegExp) 解析文本

電話

在文本中查找電話號碼的問題在於,書寫數字有很多選擇——帶或不帶連字符、通過空格、帶或不帶括號中的地區代碼等。因此,在我看來,更容易首先使用幾個嵌套函數從源文本中清除所有這些字符 替代 (代替)使它粘在一起成為一個整體,然後用一個原始的規則 d{11} 連續拉出11個數字:

在 Excel 中使用正則表達式 (RegExp) 解析文本

ITN

這裡有點複雜,因為 TIN(在我國)可以是 10 位(對於法人實體)或 12 位(對於個人)。 如果你不特別挑毛病,那麼很可能滿足於常規 d{10,12},但嚴格來說,它會拉出所有10到12個字符的數字,即錯誤輸入的11位數字。 使用由邏輯 OR 運算符連接的兩個模式會更正確 | (豎線):

在 Excel 中使用正則表達式 (RegExp) 解析文本

請注意,在查詢中,我們首先查找 12 位數字,然後才查找 10 位數字。 如果我們以相反的方式編寫正則表達式,那麼它將為每個人提取,即使是長的 12 位 TIN,也只有前 10 個字符。 即第一個條件觸發後,不再進行進一步驗證:

在 Excel 中使用正則表達式 (RegExp) 解析文本

這是運營商的根本區別 | 來自標準的 excel 邏輯函數 OR (要么),重新排列參數不會改變結果。

產品 SKU

在許多公司中,唯一標識符被分配給商品和服務——文章、SAP 代碼、SKU 等。如果它們的符號中有邏輯,那麼可以使用正則表達式輕鬆地將它們從任何文本中提取出來。 例如,如果我們知道我們的文章總是由三個大寫英文字母、一個連字符和一個隨後的三位數字組成,那麼:

在 Excel 中使用正則表達式 (RegExp) 解析文本

模板背後的邏輯很簡單。 [阿茲] – 表示拉丁字母的任何大寫字母。 下一個量詞 3{} 說對我們來說重要的是恰好有三個這樣的字母。 在連字符之後,我們正在等待三位數字,所以我們在末尾添加 d{3}

現金金額

與上一段類似,您還可以從商品描述中提取價格(成本、增值稅……)。 例如,如果貨幣金額用連字符表示,則:

在 Excel 中使用正則表達式 (RegExp) 解析文本

信號模式 d 帶量詞 + 搜索直到連字符的任何數字,並且 d{2} 之後會尋找便士(兩位數)。

如果您需要提取的不是價格而是增值稅,那麼您可以使用我們的 RegExpExtract 函數的第三個可選參數,它指定要提取的元素的序號。 而且,當然,您可以替換該功能 替代 (代替) 在結果中,標準小數分隔符的連字符並在開頭添加一個雙減號,以便 Excel 將找到的增值稅解釋為正常數字:

在 Excel 中使用正則表達式 (RegExp) 解析文本

車牌號

如果不搭乘特殊車輛、拖車等摩托車,那麼標準車號依照「字母-三個數字-兩個字母-地區代碼」的原則進行解析。而且,區域代碼可以是2位或3位數字,並且只有那些與拉丁字母相似的字母才被用作字母。因此,以下正規表示式將幫助我們從文本中提取數字:

在 Excel 中使用正則表達式 (RegExp) 解析文本

Time

要以 HH:MM 格式提取時間,以下正則表達式適用:

在 Excel 中使用正則表達式 (RegExp) 解析文本

結腸片段後 [0-5]天,因為它很容易計算出來,設置在 00-59 範圍內的任何數字。 在括號中的冒號之前,有兩種模式起作用,由邏輯 OR(豎線)分隔:

  • [0-1]天 – 00-19 範圍內的任何數字
  • 2[0-3] – 20-23 範圍內的任何數字

對於獲得的結果,您可以另外應用標準 Excel 函數 TIME (團隊)將其轉換為程序可以理解並適合進一步計算的時間格式。

密碼檢查

假設我們需要檢查用戶發明的密碼列表是否正確。 根據我們的規定,密碼只能包含英文字母(小寫或大寫)和數字。 不允許使用空格、下劃線和其他標點符號。

可以使用以下簡單的正則表達式來組織檢查:

在 Excel 中使用正則表達式 (RegExp) 解析文本

事實上,對於這樣的模式,我們要求在開始 (^) 並結束 ($) 在我們的文本中,只有方括號中給出的集合中的字符。 如果您還需要檢查密碼的長度(例如,至少 6 個字符),那麼量詞 + 可以用表格中的間隔“六或更多”代替 {6,}:

在 Excel 中使用正則表達式 (RegExp) 解析文本

來自地址的城市

假設我們需要從地址欄中提取城市。 常規程序會有所幫助,從“g”中提取文本。 到下一個逗號:

在 Excel 中使用正則表達式 (RegExp) 解析文本

讓我們仔細看看這個模式。

如果您已經閱讀了上面的文字,那麼您已經了解了正則表達式中的某些字符(句點、星號、美元符號等)具有特殊含義。 如果您需要自己查找這些字符,則它們前面有一個反斜杠(有時稱為 屏蔽)。 因此,在搜索片段“g”時。 我們必須用正則表達式寫 先生。 如果我們正在尋找一個加號,那麼 + 等。

我們模板中接下來的兩個字符,點和量詞星號,代表任意數量的任意字符,即任意城市名稱。

模板末尾有一個逗號,因為我們正在尋找來自“g”的文本。 逗號。 但是文本中可以有幾個逗號,對嗎? 不僅是城市,還包括街道、房屋等。我們的請求將停止在哪一個? 這就是問號的用途。 沒有它,我們的正則表達式將拉出可能的最長字符串:

在 Excel 中使用正則表達式 (RegExp) 解析文本

就正則表達式而言,這樣的模式是“貪婪的”。 為了糾正這種情況,需要一個問號——它使量詞“吝嗇”——我們的查詢只將文本帶到“g”之後的第一個反逗號:

在 Excel 中使用正則表達式 (RegExp) 解析文本

來自完整路徑的文件名

另一種非常常見的情況是從完整路徑中提取文件名。 表單的簡單正則表達式將在這裡有所幫助:

在 Excel 中使用正則表達式 (RegExp) 解析文本

這裡的技巧是搜索實際上是在相反的方向上發生的——從結尾到開頭,因為在我們模板的末尾是 $, 我們正在尋找它之前的所有內容,直到右邊的第一個反斜杠。 反斜杠被轉義,就像前面示例中的點一樣。

PS

“接近尾聲” 我想澄清以上所有內容只是正則表達式提供的所有可能性的一小部分。 有很多特殊字符和它們的使用規則,整本書都是關於這個主題的(我推薦至少這本書作為開始)。 在某種程度上,編寫正則表達式幾乎是一門藝術。 幾乎總是可以改進或補充發明的正則表達式,使其更優雅或能夠處理更廣泛的輸入數據。

分析和解析別人的正則表達式或調試自己的,有幾個方便的在線服務: 正則表達式101, RegExr 其他

不幸的是,並非經典正則表達式的所有功能都在 VBA 中得到支持(例如,反向搜索或 POSIX 類)並且可以與 Cyrillic 一起使用,但我認為第一次滿足您的需求就足夠了。

如果您對該主題並不陌生,並且您有一些東西要分享,請在下面的評論中留下在 Excel 中工作時有用的正則表達式。 一個頭腦是好的,但兩個靴子是一對!

  • 使用 SUBSTITUTE 函數替換和清理文本
  • 搜尋並突出顯示文字中的拉丁字符
  • 搜索最接近的相似文本(Ivanov = Ivonov = Ivanof 等)

發表評論