正規表示式中的“環視”及實際專案應用

NoTryNoSuccess發表於2019-02-16

什麼是環視(lookaround)?

  • 環視結構不匹配任何字元,只匹配文字中的特定位置,這一點與單詞分界符b、錨點^以及$相似,但是環視比它們更加通用,並且能夠檢測兩側文字。
  • 環視的四種型別
    1)順序環視-肯定(從左至右檢視文字):表示式為(?=……),匹配成功的條件為表示式能夠匹配右側文字,比如(?=d)
    2)順序環視-否定(從左至右檢視文字):表示式為(?!……),匹配成功的條件為表示式不能匹配右側文字,比如(?!d)
    3)逆序環視-肯定(從右至左檢視文字):表示式為(?<=……),匹配成功的條件為表示式能夠匹配左側文字,比如(?<=d)
    4)逆序環視-否定(從右至左檢視文字):表示式為(?<!……),匹配成功的條件為表示式不能匹配左側文字,比如(?<!)=)

環視在個人經歷專案中的兩個實際應用:

  • 團隊管理中檢測對於指定專案的許可權:專案中我們是用類似38:1,749:0,188:1這樣的字串來儲存團隊普通成員對於各使用者專案的許可權,比如其中749代表ID為749的使用者專案,冒號標記符後跟隨的0數字表示具有檢視許可權,1數字則表示兼具檢視和設定許可權,多個使用者專案許可權標記間以逗號分隔,如果對於一個使用者專案沒有任何許可權,則整個許可權字串中將不會出現該專案ID。基本結構定了之後,那麼我們其中一個類似的查詢檢測許可權問題是,已知使用者許可權字串,檢測對於指定專案比如749是否具有設定許可權,在這裡的問題情境其實就是檢測使用者許可權字串中是否包含749:1這個子字串。可以有如下幾種解決方式:
    1)可以不用正規表示式,先以逗號作為分隔符拆分許可權字串,可以得到一個陣列,該陣列每一個元素為類似749:1這樣的單個專案許可權標記子字串,再檢測這個陣列中是否存在749:1這一元素項。
    2)匹配749:1出現情況的正規表示式為^749:1|,749:1,進一步可以簡化為(^|,)749:1(注意:一個小陷阱,想想這裡如果不使用正規表示式匹配,而只使用普通字串749:1作為要查詢匹配的目標會出現什麼問題?)。
    3)利用環視的正規表示式為(?<!d)749:1(我們知道D表示非數字,那麼這裡表示式如果修改為(?<=D)749:1是否可以正常工作?)。
  • 千分位格式化數值(各分析頁中各指標塊資料用JavaScript進行逗號格式化):例如我們需要將數值298444215格式化為298,444,215,正常思維是從這個數的右邊開始,每次數3位數字,如果左邊還有數字的話,就加入一個逗號。如果我們能把這種思路直接用到正規表示式中當然很好,可惜正規表示式一般都是從左向右工作的。不過變換下思路,逗號應該加在“左邊有數字,右邊數字的個數正好是3的倍數的位置”,這樣就可以使用環視來解決這個問題了。初步的正規表示式為:(?<=d)(?=(ddd)+$),並結合開發語言的replace替換功能進行全域性匹配替換。(想想這裡如果去掉$結果會如何?)遺憾的是,JavaScript不支援逆序環視,因此如果要使用JavaScript中的正規表示式進行處理,剛剛的匹配正規表示式就需要修改為:(d)(?=(ddd)+$),並需要結合對捕獲型括號的反向引用$1進行全域性匹配替換。

相關文章