這兩天一直在時不時的和neo4j圖數據庫打交道。它的查詢語句可使用正則表達式,有一段時間沒有本身寫過正則表達式了,如今處於能看懂別人寫的正則表達式,可是本身寫不出來,語法規則都忘了。爲了方便接下來的工做,因此特意複習複習正則表達式的語法。javascript
正則表達式是用來匹配字符串的一系列匹配符,具有簡介高效的特色,在不少語言中都有支持(java、python、javascript、php等等)。在windows的cmd命令中也一樣支持,例如使用命令dir j*,那麼只會羅列出全部以j開頭的文件和文件夾。php
正則表達式在在不一樣語言的支持語法略有不一樣,本文采用js的進行說明。js中使用正則表達式的方法爲str.match(/表達式/),即須要加兩個斜槓。如下全部的代碼段第一行爲代碼,第二行爲返回結果,實驗是在chrome控制檯進行的。java
一直認爲最好的學習方式就是實際操做,理論誰都能講一大堆,可是實際作沒作出來還真不知道。一個奇葩現象就是教軟件工程的老師可能並無在軟件行業待過。python
普通匹配符能匹配與之對應的字符,默認區分大小寫。正則表達式
"Hello Regx".match(/H/)
["H", index: 0, input: "Hello Regx", groups: undefined]
複製代碼
參數直接加在最後一個斜槓的後面,好比"Hello Regx".match(/regx/==i==),能夠加多個參數。chrome
"Hello Regx".match(/regx/i)
["Regx", index: 6, input: "Hello Regx", groups: undefined]
複製代碼
以前是表達式一旦匹配成功,就再也不向字符串後面查找了,加上g後,表示進行全局查找。最後返回的是一個數組。數據庫
"Hello Regx".match(/e/g)
(2) ["e", "e"]
複製代碼
須要注意的是,上面全部的匹配符都只能匹配一個字符。編程
"Hello 2018".match(/\d/g)
// 使用\d,匹配字符串中的全部數字
(4) ["2", "0", "1", "8"]
"Hello 2018".match(/\w/g)
// 使用\w,匹配全部的數字和字母,須要注意沒有匹配到空格
(9) ["H", "e", "l", "l", "o", "2", "0", "1", "8"]
"Hello 2018".match(/./g)
// 使用.,匹配全部字符,包括空格
(10) ["H", "e", "l", "l", "o", " ", "2", "0", "1", "8"]
"Hello 2018".match(/\d\w./g)
// 分析一下這個爲何匹配到的是201,
// 首先\d找到第一個數字2,匹配成功,緊接着\w匹配到0,而後.匹配到1
// 整個正則表達式匹配成功,返回201
["201"]
"Hello 20\n18".match(/\d\w./g)
// 這裏匹配不成功,由於.不能匹配換行符,因此返回null
null
"Hello 2018".match(/\w.\d/g)
// 首先看這個正則式,\w.\d,它要求最後一個字符是數字
// \w.能一直匹配到空格,可是由於得知足\d,因此第一個匹配成功的是0 2
// 由於是全局匹配,因此會接着匹配後面的018,也匹配成功
(2) ["o 2", "018"]
複製代碼
好比中國的手機號都是以1開頭,第二位只能是三、四、五、七、8,第3位只要是數字就行。如何匹配這樣的字符串?windows
"152".match(/1[34578]\d/)
// 第二個字符能夠選擇中括號中的任意一個
["152", index: 0, input: "152", groups: undefined]
複製代碼
若是在[]添加了^,表明取反。即[^]表示除了中括號中的字符都知足。數組
"152".match(/1[^34578]\d/)
null
"1a2".match(/1[^34578]\d/)
// 只要不是[]中的字符,都知足,包括回車符
["1a2", index: 0, input: "1a2", groups: undefined]
複製代碼
咱們的手機號有11位,除了前2位有要求,其餘9位度沒有要求,那麼是否是正則表達式就應該這樣寫呢?
1[^34578]\d\d\d\d\d\d\d\d\d
複製代碼
很明顯,這樣寫太麻煩,確定有更好的方式,這裏就能夠修飾一下匹配次數啦。
例子很簡單,一看就懂,不浪費時間。
"15284750845".match(/1[34578]\d{9}/)
["15284750845", index: 0, input: "15284750845", groups: undefined]
"15".match(/1[34578]\d?/)
["15", index: 0, input: "15", groups: undefined]
"152".match(/1[34578]\d?/)
["152", index: 0, input: "152", groups: undefined]
"152".match(/1[34578]\d+/)
["152", index: 0, input: "152", groups: undefined]
"15".match(/1[34578]\d+/)
null
複製代碼
按照上面的寫法會出現下面的問題。
"ya15284750845".match(/1[34578]\d{9}/)
// 不是電話號碼,也能匹配成功,須要進一步改進
["15284750845", index: 2, input: "ya15284750845", groups: undefined]
複製代碼
"ya15284750845".match(/^1[34578]\d{9}/)
// 如今就能從一開始匹配並且還得符合正則式纔算匹配成功
null
// 可是依舊會出現下面的問題
"1528475084523255".match(/^1[34578]\d{9}/)
// 不是電話號碼也能匹配成功,還要改進
["15284750845", index: 0, input: "1528475084523255", groups: undefined]
複製代碼
"1528475084523255".match(/^1[34578]\d{9}$/)
// 如今就能保證正確了,有^表示從開始匹配;
// 有$表示持續匹配到結束,即徹底匹配
null
/* 須要注意的是,一個字符串從開始匹配和從結束匹配都沒問題, 不表明整個字符串就沒問題,好比15284750845-15284750845 這個字符串從開始和從結束匹配都能成功,但其實是錯的 */
複製代碼
到這裏發現正則表達式確實很強大,僅僅幾個簡單的符號就能匹配字符串,可是若是咱們要匹配的字符自己就是前面用到的符號怎麼辦呢?
"1.".match(/./)
//由於.能匹配除換行的全部字符,因此匹配到1
//但實際上咱們想匹配.這個字符
["1", index: 0, input: "1.", groups: undefined]
"1.".match(/\./)
// 只須要加一個轉義字符就能夠了,其餘相似
[".", index: 1, input: "1.", groups: undefined]
複製代碼
好比如今想匹配圖片的文件名,包括jpg、png、jpeg、gif等等,這是多個選項,因此須要像編程語言同樣,應該具有條件分支結構。
"1.jpg".match(/.+\.jpe?g|gif|png/)
// 這樣就能夠知足條件分支了,不過下面又出問題了
["1.jpg", index: 0, input: "1.jpg", groups: undefined]
"1.png".match(/.+\.jpe?g|gif|png/)
// 這裏沒有匹配到.和前面的文件名
["png", index: 2, input: "1.png", groups: undefined]
/* 其實咱們想告訴它的是,.和後面的每個條件分支的值都是一個獨立的總體 可是它把.+\.jpe?g、gif、png當成了各自獨立的總體 咱們並不想讓它這樣切分,因此咱們來告訴它怎麼分纔是正確的 */
"1.png".match(/.+\.(jpe?g|gif|png)/)
// 如今能夠匹配成功了,可是它多匹配了一個
// 由於括號的內容能夠進行分組,單獨匹配
(2) ["1.png", "png", index: 0, input: "1.png", groups: undefined]
// 因此最終寫法以下
"1.png".match(/.+\.(?:jpe?g|gif|png)/)
["1.png", index: 0, input: "1.png", groups: undefined]
複製代碼
// 首先看一個例子
"aabab".match(/a.*b/)
["aabab", index: 0, input: "aabab", groups: undefined]
/* 上面的匹配沒有什麼問題,但實際上aab也是能夠的 也就是aab也是符合條件的,那又是爲何呢? */
複製代碼
由於在正則表達式中,默認是貪婪模式,儘量多的匹配,能夠在修飾數量的匹配符後面添加?,則表明懶惰。
// like this (^__^)
"aabab".match(/a.*?b/)
["aab", index: 0, input: "aabab", groups: undefined]
複製代碼
到這裏應該就差很少了,再深刻的,就自我查詢知識了。