正則,毋庸置疑,是一個無比強大的工具。若是仔細留意,咱們能夠在源代碼(各類語言)、編輯器、開發者工具、命令行等地方看到正則的身影。學習使用正則,不只有趣,也是提高工做效率的一條捷徑。html
正則的經常使用概念能夠參考下表,主要熟記字符類型、錨點、轉義字符、量詞等。前端
基礎用法相信你們都很快理解,如下主要介紹各類正則斷言。node
斷言的實用性至關於給一段正則表達式提供了一個錨點,筆者在平常工做實踐中,使用頻率較高。react
模式:x(?=y)git
匹配出 x 表達式,但 x 後面必須跟着 y 表達式。github
模式:x(?!y)正則表達式
匹配出 x 表達式,但 x 後面不能跟着 y 表達式。express
模式:(?<=y)xnpm
至關明顯,匹配出 x 表達式,但 x 前必須出現 y 表達式。數組
模式:(?<!y)x
至關明顯,匹配出 x 表達式,但 x 前不能出現 y 表達式。
\1 其實就是上一個匹配到分組引用。
好比我要在 I like JJLin and Huahua~ 中匹配 Huahua,如圖:
固然如下方式也可達成:
使用量詞 + 或 *
或者用全局搜索標誌 g
使用範圍 {2}
不過,雖然條條大路通羅馬,但仍是須要注意匹配的 hua 數量。好比方法 一、2 都會盡量多的匹配。
exec() 方法在一個指定字符串中執行一個搜索匹配。返回一個結果數組或 null。
/(?<=appear\s)(\w+)[^\d]+(\d+)/g.exec("apple yummy, appear angel id 1030"); // => ["angel id 1030", "angel", "1030", index: 20, input: "apple yummy, appear angel id 1030", groups: undefined] 複製代碼
能夠看出數組第一項爲匹配的所有字符串。接下來展現了匹配到的分組(\w+) -> angel,(\d+) -> 1030。
固然筆者我的以爲 exec 最容易踩坑的點:當 exec 方法使用 "g" 標誌時,能夠屢次執行 exec 方法來查找同一個字符串中的成功匹配。
改寫以上例子,咱們將正則存爲一個變量:
const regexAngelAndId = /(?<=appear\s)(\w+)[^\d]+(\d+)/g;
regexAngelAndId.exec("apple yummy, appear angel id 1030");
// => ["angel id 1030", "angel", "1030", index: 20, input: "apple yummy, appear angel id 1030", groups: undefined]
regexAngelAndId.lastIndex;
// => 33
regexAngelAndId.exec("apple yummy, appear angel id 1030");
// => null
regexAngelAndId.lastIndex;
// => 0
複製代碼
能夠看到。當咱們存爲一個正則字面量時,查找將從該正則表達式的 lastIndex 屬性指定的位置開始。(test() 也會更新 lastIndex 屬性)。所以第二次就再也找不到相同的值了,結果天然而然爲 null。
使用 exec 時,務必仍是留意這一點。
test() 方法執行一個檢索,用來查看正則表達式與指定的字符串是否匹配。返回 true 或 false。
const regexAngelAndId = /(?<=appear\s)(\w+)[^\d]+(\d+)/g;
regexAngelAndId.test("apple yummy, appear angel id 1030");
// => true
regexAngelAndId.lastIndex;
// => 33
regexAngelAndId.test("apple yummy, appear angel id 1030");
// => false
regexAngelAndId.lastIndex;
// => 0
複製代碼
一樣和 exec 方法須要留意 "g" 標誌,再也不贅述。
上述兩個方法在 JavaScript 中很經常使用,務必牢記。
如下都是正則對象上的靜態屬性,通常來講使用頻率不大(或者我沒發現?),具體使用方法可參考 MDN 文檔 - RegExp。
固然還有不少其餘方法以及屬性,均可自查文檔。
在字符串對象上使用正則也是十分常見的操做。你們可能知道 replace、match 方法能夠用正則,可是日常還有 search、split,甚至很新鮮出爐的 matchAll 方法均可以幫助咱們更好的在字符串上使用正則。
這裏比較有趣的是 matchAll 方法,這個方法的出現完美的取代了用 Regexp.exec()方法循環匹配信息。
使用 matchAll 會獲得一個迭代器的返回值,可使用 for...of, 擴展運算符, 或者 Array.from() 來進行取值。十分便利。
關於這些 API 最好的學習方式,可參考文檔:MDN 文檔 - String
在咱們的 vscode 裏也有正則的用武之地!
好比說咱們須要全局查找文件中 console.error 的值,並將其替換。就可使用如下操做。(普通的文本查找可作不到這種姿式)
前提是要勾選使用正則的選項(紅色箭頭所指處)
或者單個文件查找替換也是能夠的。
在咱們熟悉的瀏覽器中,可使用正則來篩選網絡請求。
固然若是存在極大量日誌的狀況下,正則也能夠幫助咱們快速定位某項日誌。
固然控制檯 source 面板身爲一個編輯器,也確定少不了正則查找的功能。
這裏主要介紹命令行中最經常使用的文本處理工具 grep。(除此以外還有 sed、awk)。grep 全名爲"Global search Regular Expression and Print out the line"。
見名思義,grep 能夠與正則結合進行文本匹配。
假設咱們有文本以下:
$ cat tinytext
apple yummy
appear angle
and wisper: "ANGLE"
複製代碼
咱們想要匹配 angle 單詞的行
$ grep "angle" tinytext
appear angle
複製代碼
成功!
若是咱們想要忽略大小寫敏感,能夠加上 "-i" 或者 "--ignore-case" 選項。(默認 grep 是大小寫敏感)。
$ grep -i "angle" tinytext
appear angle
and wisper: "ANGLE"
複製代碼
許多時候,咱們並不想匹配行,而想匹配關鍵字,此時能夠加上 "-o" 或則 "--only-matching" 選項。
$ grep -io "angle" tinytext
angle
ANGLE
複製代碼
以上咱們都只是普通文本匹配,grep 支持基本正則表達式,咱們可使用 "-E" 或者 」"--extended-regexp" 選項使用擴展正則表達式。
好比咱們想匹配出 yummy 前的單詞,我稍微一考慮,就寫出如下規則:匹配至少大於一個 a-z 字符組成的,而且後面必須跟着一個空格及 yummy 的一個單詞。
$ grep -oE "[a-z]+(?=\syummy)" tinytext
grep: repetition-operator operand invalid
複製代碼
可是,不幸的發現失敗了。通過一番查找,發現 grep 默認不支持 "?=" 操做符。可是不要急,在 mac 系統中能夠經過如下命令升級咱們的工具箱。
$ brew insall grep
...
...
All commands have been installed with the prefix "g".
複製代碼
因而咱們得到了 ggrep 這個工具,而後能夠加上 "-P" 或者 "--perl-regexp" 使用兼容 Perl 的正則引擎(得以支持 "?=" 等操做符)。
$ ggrep -oP "[a-z]+(?=\syummy)" tinytext
apple
複製代碼
成功了!
相信常常用命令行處理工具的同窗都會承認 grep 的實用性(前端同窗可能比較陌生,可是建議學習)
筆者有個困擾,常常開發項目的時候須要知道本身筆記本的 ip 地址。這時候我會敲入 ifconfig 而後肉眼一頓搜索,每次都得浪費幾秒,才能找到 ip 地址。
此時 grep 命令發揮了做用
$ ifconfig | ggrep -oP "(?<=inet\s)\d{1,3}(\.\d{1,3}){3}"
127.0.0.1
192.168.31.254
複製代碼
成功獲取到 ip 地址。可是 127.0.0.1 咱們其實並不須要。咱們能夠加上選項 "-v" 或者 "--invert-match" 反向排除掉本地 ip。
$ ifconfig | ggrep -oP "(?<=inet\s)\d{1,3}(\.\d{1,3}){3}" | ggrep -vP "127[\d\.]+"
172.20.10.13
複製代碼
噌噌噌!簡簡單單~咱們能夠將以上命令配置爲 bash 別名 alias get-ip='...'
,這裏不詳細介紹。我以前的博客有提到。
$ get-ip
192.168.31.254
複製代碼
好比咱們須要尋找端口 8001 的 node 應用程序進程 PID。
咱們經過命令 lsof -i tcp:8001
$ lsof -i tcp:8001
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
node 87701 yanguangjie 23u IPv6 0x42c450e30b40bcb 0t0 TCP *:vcom-tunnel (LISTEN)
複製代碼
使用 grep 匹配出 node 應用程序 PID。
$ lsof -i tcp:8001 | ggrep -oP "(?:node[^\d]+)\d+(?=\s)" | egrep -o "\d+"
87701
複製代碼
要問匹配 PID 出來有什麼用?固然是強制殺掉它了!
$ kill -9 $(lsof -i tcp:8001 | ggrep -oP "(?:node[^\d]+)\d+(?=\s)" | egrep -o "\d+")
複製代碼
固然若是以爲以上方式略顯麻煩的同窗,能夠基於以上腳本寫個工具,減小重複工做。
這裏筆者寫了一個簡易的工具 k-port,若感興趣的同窗能夠去看看以及使用。
$ npm install -g k-port
$ k-port 8001,8003
total ports: [ '8001', '8003' ]
get PID 2152 by port: 8001
kill PID 2152 ok.
get PID 2164 by port: 8003
kill PID 2164 ok.
複製代碼
快速過濾出 react 的全部 alpha 版本。
$ npm view react versions | ggrep -oP "[^\s]+alpha[^\s]+"
複製代碼
到此爲止,也只是比較膚淺的介紹了一下有限的,我知道的正則的各類使用方式,固然~因此歡迎你們補充。正則是實踐性極強的一門工具,或者說是藝術也不爲過。多上手練習和使用。
感謝閱讀~