正則匹配:REGEXP_SUBSTR()怎樣提取復(fù)雜文本中的特定模式片段?

regexp_substr() 是數(shù)據(jù)庫中用于提取符合正則表達式內(nèi)容的函數(shù),其語法為 regexp_substr(source_string, pattern [, position [, occurrence]]),支持從指定位置查找特定次數(shù)的匹配結(jié)果。一、基本用法是從字符串中提取符合正則的部分,例如從日志提取 ip 地址;二、oracle 支持通過參數(shù)提取子組內(nèi)容,而 mysql 需外部處理;三、可通過靈活正則提取多行文本中的目標(biāo)信息,如電話號碼;四、使用時需注意大小寫敏感、NULL 返回值、貪婪匹配及特殊字符轉(zhuǎn)義等問題。

正則匹配:REGEXP_SUBSTR()怎樣提取復(fù)雜文本中的特定模式片段?

REGEXP_SUBSTR() 是很多數(shù)據(jù)庫系統(tǒng)(比如 oraclemysql)里用來提取符合特定正則表達式片段的函數(shù)。它比普通的字符串查找更強大,尤其適合處理復(fù)雜文本結(jié)構(gòu)。

正則匹配:REGEXP_SUBSTR()怎樣提取復(fù)雜文本中的特定模式片段?


一、基本用法要清楚

REGEXP_SUBSTR() 的基本語法是:

正則匹配:REGEXP_SUBSTR()怎樣提取復(fù)雜文本中的特定模式片段?

REGEXP_SUBSTR(source_string, pattern [, position [, occurrence]])
  • source_string:你要從中提取內(nèi)容的原始文本
  • pattern:你寫的正則表達式
  • position(可選):從第幾個字符開始搜索,默認是1
  • occurrence(可選):匹配第幾次出現(xiàn)的結(jié)果,默認是1

舉個簡單例子:
你想從一段日志中提取 IP 地址,日志類似 “User login from 192.168.1.100 at 14:30″,你可以這樣寫:

SELECT REGEXP_SUBSTR('User login from 192.168.1.100 at 14:30', 'd+.d+.d+.d+') AS ip;

結(jié)果就是 192.168.1.100。

正則匹配:REGEXP_SUBSTR()怎樣提取復(fù)雜文本中的特定模式片段?


二、如何提取多個括號中的內(nèi)容?

REGEXP_SUBSTR 只返回第一個完整匹配,但它支持用括號分組并提取子表達式,不過具體語法因數(shù)據(jù)庫而異。

以 Oracle 為例,可以加一個參數(shù)來指定子組:

REGEXP_SUBSTR(text, 'abc(d+)xyz', 1, 1, NULL, 1)

上面這個表達式會匹配形如 abc123xyz 的內(nèi)容,并提取出里面的數(shù)字部分 123。

注意:MySQL 不直接支持子組提取,只能靠正則整體匹配后在外部再處理。


三、處理多行或多段數(shù)據(jù)的小技巧

有時候你需要從一段雜亂無章的文字中提取多個目標(biāo)內(nèi)容。例如下面這種文本:

訂單編號:A12345 客戶姓名:張三 聯(lián)系電話:13800138000 地址:北京市朝陽區(qū)xx路xx號

如果你想提取電話號碼,可以用這樣的正則:

REGEXP_SUBSTR(content, '聯(lián)系電話:(d{11})', 1, 1, NULL, 1)

這樣就能準確提取手機號了。

如果你不確定格式是否一致,比如“聯(lián)系電話”后面可能有空格或冒號變化,可以放寬正則限制:

聯(lián)系電話s*:s*(d{11})

這樣即使中間有多個空格或者沒寫規(guī)范也能匹配上。


四、一些容易踩坑的地方

  • 正則不區(qū)分大小寫? 默認是區(qū)分的,如果想忽略大小寫,可以在正則里加 ‘i’ 標(biāo)志(Oracle 支持,MySQL 不支持)
  • 找不到就返回 NULL:這是默認行為,要注意 SQL 中對 NULL 的處理
  • 貪婪 vs 非貪婪:正則默認是貪婪模式,可能會匹配過多內(nèi)容,這時候要在量詞后加 ?,比如 .*?
  • 特殊字符需要轉(zhuǎn)義:像 .、(、)、[ 等符號在正則中有特殊含義,要用 轉(zhuǎn)義

基本上就這些。掌握好正則寫法和數(shù)據(jù)庫的具體實現(xiàn)差異,REGEXP_SUBSTR 就能幫你搞定大多數(shù)文本提取任務(wù)。

? 版權(quán)聲明
THE END
喜歡就支持一下吧
點贊15 分享