玩出花來的正則

前言

技術羣裏有人提問:請教一個正則 能夠輸入正負9位整數2位小數,小數能夠不輸入。因而,八仙過海,各顯神通!前端

羣裏大佬的回答

很快,就有一位大佬發來一個他之前寫的保留 2 位小數正則面試

// 這個正則是利用分組的方法,先匹配有沒有減號,,而後匹配數字,而後匹配小數點,最後匹配2位小數

/^(\-)*(\d+)\.(\d{2})+.*$/
複製代碼

明顯這個大佬的正則達不到提問同窗的的需求,因而又有大佬給出了他的正則正則表達式

// 這個正則首先利用了?號的非貪婪模式匹配減號,而後匹配9位數,而後又用?號匹配是否有小數點

/^-?[0-9]{9}(\.[0-9]{2})?$/
複製代碼

很快有人指出這個只能固定9位數,數字不能是固定的,大佬又修改了一版post

// 這個已經稍微能用了,能夠匹配正負9位整數2位小數,小數能夠不輸入

/^-?[0-9]{1,9}(\.[0-9]{1,2})?$/
複製代碼

急速(大概1~2秒鐘),又有大佬指出,上面的正則能夠匹配首位數爲0的狀況,通常來講,數字的首位數不能爲0性能

首位數字不能爲0,那就加個判斷就行了,因而正則改成優化

// 改成匹配首位數只能是1~9,不能爲0

/^-?[1-9]{1}[0-9]{0,8}(\.[0-9]{1,2})?$/
複製代碼

光速(幾乎秒發),槓精(😀)提問:若是是是零點幾的狀況呢,或者就是整數0呢搜索引擎

大佬無奈給出spa

// 在分組和非貪婪匹配的基礎上,又加上了與或非的概念,匹配整數,或者零點幾的2位小數,或者是N位整數的2位小數

/^-?(([1-9][0-9]*)|(([0]\.\d{1,2}|[1-9][0-9]*\.\d{1,2})))$/
複製代碼

可是這位大佬估計是沒看清題目,沒有限制整數的位數,因而又有大佬發出正則,逐漸複雜3d

// 根據前面大佬的正則修改了一下,匹配前面不能爲0的2爲小數,或者零點幾的2位小數,或者0

/^(-?[1-9]{1}[0-9]{0,8}(\.[0-9]{1,2})?)|(0(\.[0-9]{1,2}))|(0)$/
複製代碼

有大佬感受上面的正則都有點長,給出一個短的code

// 這個大佬喜歡使用集合,匹配加減號的集合,匹配任意數字的集合,匹配小數點的集合

/[+-]?[\d]{1,9}(\.[\d]{1,2})?/
複製代碼

結合上面各位大佬的正則,有人給出

// 集合匹配加減號,匹配非零開頭的2位小數,或者零開頭的小數

/^[+-]?(([1-9][0-9]{0,8})|0)(\.[0-9]{1,2})?$/
複製代碼

討論到這裏告一段落,我等萌新看的是瑟瑟發抖,徹底不敢說話。

tips:記得轉string再用test判斷,使用數字類型進入判斷,最前面的0會自動給去掉

前端如何去寫正則

在前端的項目中,會有許多須要正則的地方,那麼如何去寫一個正則呢?

有不少人說過正則不用去記,是的,大部分不用記。可是咱們如何去寫正則仍是有必要去記一下的,這裏我本人總結7條

  • 一、任何複雜的正則均可以用()號分組簡單化
  • 二、| 這個符號是個好東西,或者或者或者,正則就出來了
  • 三、^ 開頭,$ 結尾
  • 四、若是要這個正則匹配所有,屢次查找,就在最後面的 / 下面加個g,也就是 /g
  • 五、若是不區分大小寫加個 i ,也就是 /i
  • 六、合理使用搜索引擎,仍是直接給一個搜索詞吧:正則表達式速查表
  • 七、實在是本身寫不出來,就搜索有沒有寫好的,或者去技術羣裏問大佬,要是沒有大佬回覆,就發個紅包

正則表達式優化

當咱們會本身寫正則以後,就要考慮一個問題了,如何寫好一個高效率的正則,舉個例子:

// 好比說咱們有一個字符串
const string = "TypeError: Cannot read property 'fundAbbrName' of undefined at Proxy.render (eval at";

// 咱們要截取TypeError: 到 (eval 之間的數據,使用正則
const reg = /(?:TypeError\:)(.*?)(?=\(eval)/

複製代碼

使用RegexBuddy檢測須要283步

修改一下:

const reg = /TypeError\:(.*?)\(e/
複製代碼

使用RegexBuddy檢測須要212步

再優化一下,改動一個單詞,把 * 改爲 +

const reg = /TypeError\:(.+?)\(e/
複製代碼

步數減小了,如今須要209步

加一個限定條件 \s

const reg = /TypeError\:\s(.+?)\(e/
複製代碼

又少了2步,如今只須要207步

改一下前面的限定條件

const reg = /\w+\:\s(.+?)\(e/
複製代碼

進入200步之內了,199步

終極優化

const reg = /\w+\:(.+)\(/
複製代碼

只需35步

經過上面的例子咱們能夠得出一些正則優化方面的心得:

  • 當要捕獲組的時候,使用非捕獲型括號(?:),可是某些時候使用沒必要要的(?:)反而會形成性能的浪費
  • 使用一些匹配規則可以提升正則的效率,好比說用 \w+ 替代 TypeError
  • 若是確認至少匹配1次,那麼請用 + 號替代 * 號
  • 若是確認匹配的數量,請用 {n,m} 替代 + 號
  • 在大多數的狀況下,限定條件多,會提升正則的效率
  • 儘可能使用非貪婪模式 ? ,可是,在某些狀況下,不使用非貪婪模式反而效率會更快

最後

本人水平有限,又錯誤之處但願各位大佬指出!

關於正則,我還寫過一篇文章記一次面試題,正則表達式(?=a)是什麼意思?,大佬們有空能夠去看看。

相關文章
相關標籤/搜索