使用正規表示式找出所有不包含某字串的行

CarterLi發表於2018-03-05

之前寫 Webpack 配置的時候遇到這樣一個問題:

通過 /.(jpg|png|svg|gif|webp)$/ 判斷圖片檔案,如果符合條件則將其儲存至 images 目錄下。
然而這樣做會把類似 fontawesome-webfont.svgglyphicons-halflings-regular.svg 這樣的字型檔案也匹配進去

這是一個強迫症患者所不能接受的。那麼問題來了:如何使用正則式匹配一段文字不包含某個字串呢?

匹配某段文字不以某字串結尾

比如需要匹配一段文字不以 some_text 結尾

  • 負值字符集合
/.*[^s][^o][^m][^e][^_][^t][^e][^x][^t]$/

比較容易想到的方式。雖然笨了點,但的確是有效的方法。但這樣做只能匹配長度≥9的字串,而且只能判斷不以某一個字串結尾。

  • 零寬度負預測先行斷言

零寬度負預測先行斷言 判斷斷言出現的位置不匹配某個表示式。

/(?!some_text).{9}$/

該正則式斷言最後任意九個字元不是some_text。同樣只能匹配長度≥9的字串。好處是用於斷言的字串是一個表示式,通過 | 可以寫任意多組字串。

  • 零寬度負回顧後發斷言

零寬度負預測後發斷言 判斷斷言出現的位置之前不匹配某個表示式。它進入 EcmaScript 標準比較晚,Chrome 62 才提供支援。

/(?<!some_text)$/

該正則式斷言行尾之前的字串不是some_text。這樣寫就對字串長度沒有限制,是最完美的寫法,可惜瀏覽器支援度較差。

  • 原生 JS 方法
str.endsWith(`some_text`)

匹配某段文字不以某字串開頭

比如需要匹配一段文字不以 some_text 開頭

  • 負值字符集合
/^[^s][^o][^m][^e][^_][^t][^e][^x][^t]/

好想,但同樣只能匹配長度≥9的字串。

  • 零寬度負預測先行斷言
/^(!some_text)/

匹配行首位置後不出現 some_text。沒有字串長度限制,也沒有瀏覽器相容性問題。

  • 原生 JS 方法
str.startsWith(`some_text`)

匹配某段文字不包含某字串

比如匹配某段文字不包含字串 some_text

  • 零寬度負預測先行斷言
/^((?!some_text).)*$/

正則式斷言該段文字的任意位置都不出現 some_text。這樣理解:

/^(?!some_text).(?!some_text).(?!some_text).(?!some_text).(?!some_text).(?!some_text).……$/

  • 原生 JS 方法
str.includes(`some_text`) // ES2016,注意不是 contains
str.indexOf(`some_text`) >= 0 // 相容性更好

相關文章