正則系列——正則虐我千百遍,我要反抗了

若是你正則基礎爲0,請先看第一篇文章:JavaScript正則表達式入門心得javascript

實戰篇

上一章我分享了正則入門的一些體會以及注意事項。這一章開始挑一些經常使用的比較複雜一點的需求來練習一下。java

場景1:驗證email是否合法

郵箱種類太多太多,什麼net後綴,特殊的咱們不作處理,下面我找了經常使用的一些郵箱:git

hyy@gmail.com  谷歌郵箱
hyy12@qq.com  qq郵箱
hyy-123@163.com  163郵箱
732662@sina.com  新浪郵箱
hyy@sohu.com  搜狐郵箱
hyy@hotmail.com  hotmai郵箱
hyy@189.cn  189郵箱
hyy@139.com  139郵箱

一、分析規則github

xxx前綴:能夠是數字、字母、-的組合
@:這個單字符匹配便可
後綴:英文或者數字
.:點分隔符
結尾:com或者cn

二、從第一個規則開始匹配
前綴能夠是數字、字母、-的組合,-的特色是隻能寫在數字或者字母中間,不能放在收尾兩邊。正則表達式

\w+-?\w+ //表示數字或者字母,中間能夠插入-。

匹配結果,加粗部分
hyy@gmail.com 谷歌郵箱
hyy12@qq.com qq郵箱
hyy-123@163.com 163郵箱
732662@sina.com 新浪郵箱
hyy@sohu.com 搜狐郵箱
hyy@hotmail.com hotmai郵箱
hyy@189.cn 189郵箱
hyy@139.com 139郵箱segmentfault

三、匹配@字符數組

\w+-?\w+@

匹配結果,加粗部分
hyy@gmail.com 谷歌郵箱
hyy12@qq.com qq郵箱
hyy-123@163.com 163郵箱
732662@sina.com 新浪郵箱
hyy@sohu.com 搜狐郵箱
hyy@hotmail.com hotmai郵箱
hyy@189.cn 189郵箱
hyy@139.com 139郵箱性能

四、後面的規則就很簡單了學習

/\w+-?\w+@\w+.(com|cn)/g

查看匹配結果測試

clipboard.png

場景2:驗證時間格式

時間格式有不少,若是要寫一個大正則來匹配全部,挺難,下面咱們只匹配xxxx-xx-xx。

2017-09-15

一、分析規則
這裏分爲幾個點,年、月、日
年:4位數字,1或2開頭
月:2位數字,0或1開頭
日:1位數字的時候是1-9,2位數字的時候,第一位是0-3,第二位是0-9

二、匹配年
日期正則是最難寫的之一,要寫得很精確,很是難。
第一位數字1或者2,使用(1|2){1},2-4位是0-9,寫成[0-9]{3},組合起來就是年

/(1|2){1}[0-9]{3}/g

clipboard.png

三、匹配月
年和月之間的鏈接符寫成-

/(1|2){1}[0-9]{3}-/g

月的組成分爲0開頭和1開頭2種狀況,若是是0開頭,第一位的0也能夠不存在,第二位是0-9。若是是1開頭,第二位是0-2,組合起來就是(0?[1-9]|1[0-2])

/(1|2){1}[0-9]{3}-(0?[1-9]|1[0-2])/g

clipboard.png

四、匹配日
日期第一位是0的時候,第二位是0-9,第一位是1的時候,第二位是0-9,第一位是2的時候,第二位是0-9,第一位是3的時候,第二位是0-1,則(0[1-9]|1[0-9]|2[0-9]|3[0-1])

/(1|2){1}[0-9]{3}-(0?[1-9]|1[0-2])-(0[1-9]|1[0-9]|2[0-9]|3[0-1])/g

clipboard.png

五、日期格式類型不少,你應該按照你工做須要去寫規則,這裏我列舉這麼可能是爲了練習多種規則的組合寫法。

場景3:驗證URL是否合法

url正則也是一個複雜的場景,我找了幾個不同的url來測試

https://segmentfault.com/write
https://shimo.im/doc/ME90WXr4Hm8nx3Jl?r=PPGD2D
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Caching_FAQ
https://regex101.com/
http://www.baidu.com/#/about
http://www.baidu.com

此次咱們省略步驟,直接分析,先是開頭,2種寫法,http://https://

/https?:\/\//g

接着看域名,多是xx.com,也多是yy.xx.com

/https?:\/\/\w+.\w+(.\w+)?\/?/g

clipboard.png

到了後面,規則變的很是複雜,我也不是很是瞭解url域名以後的全部寫法,就從我一開始寫的測試集來看,能夠寫成下面的形式

/https?:\/\/\w+.\w+(.\w+)?\/?([\w-_#\/\?=.]+)?/g

clipboard.png

這個正則雖然匹配出來了因此測試樣例,可是他是有缺陷的,我在網上也看了其餘的一些寫法,測試以後都有問題,如何寫出一個精確度很是高的url正則,還須要你的努力。

場景4:獲取url的參數

網上的正則是使用window.location.search來獲取問號後面的參數字符,我使用了一種純正則實現的新方法。url可傳可不傳。

function getUrlParamName(name, url) {
  if (typeof name !== 'string') throw Error('必須是字符串')
  if (!url) {
    //若是沒有傳url,則讀取當前網站的url
    url = window.location.href
  }
  //匹配出name=value的數組
  let arr = url.match(/(?!(?:(\?|\&)))(\w+)=(\w+)/g);
  for(let v of arr){
    //若是某個元素和傳入參數組成的字符串恰好匹配,則返回該value。
    if(new RegExp(name + '=([0-9a-zA-Z]+)', 'g').test(v)) {
      return v.match(new RegExp(name + '=([0-9a-zA-Z]+)', 'i'))[1]
    } 
  }
  return null
}
let t = getUrlParamName('r')
console.log(t) // PPGD2D

方法你能夠花時間慢慢研究,我在這裏教你一個新知識,叫作零寬斷言。

(?!(?:(\?|\&)))(\w+)=(\w+)

這裏用到的語法以下:分爲左右2個括號,左邊的(?!(?:(?|&)))表示匹配到?或者&,可是不獲取這2個符號,而是獲取跟着它後面匹配的正則。

s = "?r=abc&qId=123"
(?!(正則))(正則) // 匹配的是r=abc , qId=123

零寬斷言這一塊我尚未完成掌握,它的大概意思是,獲取某個字符或者某些字符前面的正則或者後面的正則。並不高大上,估計是某人翻譯的時候,取了個裝逼的名字吧。

總結

本章分享了4個場景的實踐,我本人不是正則大神,也是剛剛開始研究正則,發現學習正則,最重要的一點是要知道當前需求的規則,「無規則無正則」,正則還有不少符號須要記住,下一步再多練一些正則題目,而後再看看基礎文檔鞏固一下知識。
好的正則大神能夠寫出性能很是好的表達式,正則和js同樣,不一樣的寫法也會有性能的差距。數據量小的時候能夠忽略,當長文本分析時,就須要你成爲一個優秀的正則大神了。

下一章:正則表達式理論鞏固篇

正則系列文章整理到了github:https://github.com/hyy1115/Re...

相關文章
相關標籤/搜索