為什麼大家都不喜歡用正則表達式?


可能跟樓主所接觸的周圍工程師有關吧。多數人不喜歡,跟看不懂,不會用,不會寫正則有關,也很難寫出精確的、高效的正則。更多的沒必要用,或有更好的解決方式。

「正則」這個詞,估計很多人第一次聽到這個名字就覺得很奇怪。何況看上去更是一對雜亂無章的字元串,比如

(?:(?:^(?:s+)?)|(?:(?P&[""])[^(?P=quote)]+?(?P=quote)[^`]*?))`(?P&[^`]+)`

看上去就頭暈,更沒胃口去學了。

正則不光看上去奇怪,而且還分兩種正則引擎DFA、NFA,更有很多流派,比如PCRE 、POSIX/GNU BRE 、POSIX/GNU ERE,尤其是做運維的同事,發現明明grep下可以正常匹配的正則,在awk下,就無法正常匹配了。

DFA引擎的mysql、egrep、flex、awk

NFA引擎的perl、java、grep、more、vi、PHP(PHP老版本里,還有三套類庫)

還有DFANFA引擎混合的逆天做法的TCL語言

這.....估計很多人都掩面而逃了... 更多的是平時工作用不到,極少用到,故也懶得學。

遇到正則需求了,網上搜一個?

能看懂還不行,還得會寫。

會寫還不行,寫出的正則還要精確匹配。

精確匹配還不行,還得寫的高效,CPU不會爆棧。

記得幾年前看到過淘寶的一個團隊BLOG上寫的java正則導致CPU100%的問題,也是正則寫不到引起的(原BLOG地址可能關了,找了個複製版Java正則引發的思考)。尤其是NFA回溯特性,一旦寫不好,隨著字元串的長度增加,回溯點將是幾何級增長,CPU都累死了。

其實,也還好,運維朋友,在做nginx、apache規則時,會經常接觸NFA 正則寫法,應該稍微熟悉點。還有就是做各種日誌分析的運維,正則基礎會好點。

還有就是做語法掃描,做各種語言語法分析的大神,比如對mysql 的sql語句分析,對php、python、go這種語言的源碼語法分析的大神,對正則更是熟悉。 比如 @vczh 輪子哥

對於更對向我這種腳本級屌絲程序員(我是PHP程序員,別打我。),接觸更多的是對IP、日期、郵箱等簡單的字元串匹配,往往都在網上隨便找找就用了,其實還是建議大家認真學學,挺有用的,也很有意思。

引用一段話。

發明BSD、TCP/IP、csh、vi和NFS的SUN首席科學家Bill Joy說過,在計算機體系結構領域裡,緩存是唯一稱得上偉大的思想的。其他的一切發明和技術不過是在不同場景下應用這一思想而已。在計算機軟體領域裡,情形也大體相似。如果羅列這個領域的偉大發明,絕對不超過二十項。這些包括分組交換網路、WEB、lisp、哈希演算法、UNIX、編譯技術、關係模型、面向對象、XML這些大名鼎鼎的傢伙,而正則表達式絕對不應該被漏掉。

正則這種神器,你們可以花時間嗎,花點兒,哪怕瞟呢,花不了多少時間!


之前也嘗試學習正則表達式,發現根據網上的快速入門指南之類的學不會,主要是記不住。

心想:正則表達式都靠記呀,而且好像每種語言里的都不一樣似的。遂放棄。

後來不小心遇到了Udacity的CS262課Programming Languages,將正則表達式與有限狀態機放在一起講,突然就明白了。

有的時候原理真的很重要,原理明白了,才能學得進去呀。

另外,這門課真的很好!主要講的是用Python來寫HTML和JS的解析器。

雖然我只學了一個單元(昨天才開始看的),但是,還是強烈安利,這是學習正則表達式的利器,由淺入深,循序漸進,至大徹大悟(我猜的)。


不喜歡嗎?我很喜歡啊,很好用啊。

說難寫的,說不容易學的,都是沒遇到好的工具吧。

推薦RegexBuddy。


談不上喜歡不喜歡

只是每次寫正則都感覺自己在罵代碼 。。。

一片【根據國家相關法律法規和政策,該信息不予顯示】。。。

/^w+([-+.]w+)*@w+([-.]w+)*.w+([-.]w+)*$/ /^[a-zA-Z][a-zA-Z0-9_]{2,6}$/


普通人有三件東西看不懂:醫生的處方,道士的鬼符,程序員得正則表達式,以為她很難讓你讀懂她。


Some
people, when confronted with a problem, think "I know, I"ll use regular
expressions." ——

——Now they have two problems.

出處不詳


作者:vczh

s*(?:&<#OPCODE&>w[a-zA-Z0-9_]*)(s*((?:&<#REGISTER0&>(AL|AH|CL|CH|DL|DH|BL|BH|AX|CX|DX|BX|SI|DI|SP|BP|EAX|ECX|EDX|EBX|ESI|EDI|ESP|EBP|ST0|ST1|ST2|ST3|ST4|ST5|ST6|ST7))|((?:&<#PTRTYPE0&>(?:int8|int16|int32|fp32|fp64))s+[((?:&<#BASE0&>(AL|AH|CL|CH|DL|DH|BL|BH|AX|CX|DX|BX|SI|DI|SP|BP|EAX|ECX|EDX|EBX|ESI|EDI|ESP|EBP|ST0|ST1|ST2|ST3|ST4|ST5|ST6|ST7))|(?:&<#INDEX0&>(AL|AH|CL|CH|DL|DH|BL|BH|AX|CX|DX|BX|SI|DI|SP|BP|EAX|ECX|EDX|EBX|ESI|EDI|ESP|EBP|ST0|ST1|ST2|ST3|ST4|ST5|ST6|ST7))*(?:&<#SCALE0&>[1248])|(?:&<#INDEX0&>(AL|AH|CL|CH|DL|DH|BL|BH|AX|CX|DX|BX|SI|DI|SP|BP|EAX|ECX|EDX|EBX|ESI|EDI|ESP|EBP|ST0|ST1|ST2|ST3|ST4|ST5|ST6|ST7))*(?:&<#SCALE0&>[1248])+(?:&<#BASE0&>(AL|AH|CL|CH|DL|DH|BL|BH|AX|CX|DX|BX|SI|DI|SP|BP|EAX|ECX|EDX|EBX|ESI|EDI|ESP|EBP|ST0|ST1|ST2|ST3|ST4|ST5|ST6|ST7))|((?:&<#INTEGER0&>(+|-)?d+)|$(?:&<#CHARA0&>.)|w$(?:&<#CHARW0&>.)|(?:&<#NAME0&>w[a-zA-Z0-9_]*))|(?:&<#BASE0&>(AL|AH|CL|CH|DL|DH|BL|BH|AX|CX|DX|BX|SI|DI|SP|BP|EAX|ECX|EDX|EBX|ESI|EDI|ESP|EBP|ST0|ST1|ST2|ST3|ST4|ST5|ST6|ST7))+((?:&<#INTEGER0&>(+|-)?d+)|$(?:&<#CHARA0&>.)|w$(?:&<#CHARW0&>.)|(?:&<#NAME0&>w[a-zA-Z0-9_]*))|(?:&<#INDEX0&>(AL|AH|CL|CH|DL|DH|BL|BH|AX|CX|DX|BX|SI|DI|SP|BP|EAX|ECX|EDX|EBX|ESI|EDI|ESP|EBP|ST0|ST1|ST2|ST3|ST4|ST5|ST6|ST7))*(?:&<#SCALE0&>[1248])+((?:&<#INTEGER0&>(+|-)?d+)|$(?:&<#CHARA0&>.)|w$(?:&<#CHARW0&>.)|(?:&<#NAME0&>w[a-zA-Z0-9_]*))|(?:&<#INDEX0&>(AL|AH|CL|CH|DL|DH|BL|BH|AX|CX|DX|BX|SI|DI|SP|BP|EAX|ECX|EDX|EBX|ESI|EDI|ESP|EBP|ST0|ST1|ST2|ST3|ST4|ST5|ST6|ST7))*(?:&<#SCALE0&>[1248])+(?:&<#BASE0&>(AL|AH|CL|CH|DL|DH|BL|BH|AX|CX|DX|BX|SI|DI|SP|BP|EAX|ECX|EDX|EBX|ESI|EDI|ESP|EBP|ST0|ST1|ST2|ST3|ST4|ST5|ST6|ST7))+((?:&<#INTEGER0&>(+|-)?d+)|$(?:&<#CHARA0&>.)|w$(?:&<#CHARW0&>.)|(?:&<#NAME0&>w[a-zA-Z0-9_]*)))])|((?:&<#INTTYPE0&>(?:int8|int16|int32|fp32|fp64))s+((?:&<#INTEGER0&>(+|-)?d+)|$(?:&<#CHARA0&>.)|w$(?:&<#CHARW0&>.)|(?:&<#NAME0&>w[a-zA-Z0-9_]*)))|((?:&<#LABEL0&>@w[a-zA-Z0-9_]*)))(s*,s*((?:&<#REGISTER1&>(AL|AH|CL|CH|DL|DH|BL|BH|AX|CX|DX|BX|SI|DI|SP|BP|EAX|ECX|EDX|EBX|ESI|EDI|ESP|EBP|ST0|ST1|ST2|ST3|ST4|ST5|ST6|ST7))|((?:&<#PTRTYPE1&>(?:int8|int16|int32|fp32|fp64))s+[((?:&<#BASE1&>(AL|AH|CL|CH|DL|DH|BL|BH|AX|CX|DX|BX|SI|DI|SP|BP|EAX|ECX|EDX|EBX|ESI|EDI|ESP|EBP|ST0|ST1|ST2|ST3|ST4|ST5|ST6|ST7))|(?:&<#INDEX1&>(AL|AH|CL|CH|DL|DH|BL|BH|AX|CX|DX|BX|SI|DI|SP|BP|EAX|ECX|EDX|EBX|ESI|EDI|ESP|EBP|ST0|ST1|ST2|ST3|ST4|ST5|ST6|ST7))*(?:&<#SCALE1&>[1248])|(?:&<#INDEX1&>(AL|AH|CL|CH|DL|DH|BL|BH|AX|CX|DX|BX|SI|DI|SP|BP|EAX|ECX|EDX|EBX|ESI|EDI|ESP|EBP|ST0|ST1|ST2|ST3|ST4|ST5|ST6|ST7))*(?:&<#SCALE1&>[1248])+(?:&<#BASE1&>(AL|AH|CL|CH|DL|DH|BL|BH|AX|CX|DX|BX|SI|DI|SP|BP|EAX|ECX|EDX|EBX|ESI|EDI|ESP|EBP|ST0|ST1|ST2|ST3|ST4|ST5|ST6|ST7))|((?:&<#INTEGER1&>(+|-)?d+)|$(?:&<#CHARA1&>.)|w$(?:&<#CHARW1&>.)|(?:&<#NAME1&>w[a-zA-Z0-9_]*))|(?:&<#BASE1&>(AL|AH|CL|CH|DL|DH|BL|BH|AX|CX|DX|BX|SI|DI|SP|BP|EAX|ECX|EDX|EBX|ESI|EDI|ESP|EBP|ST0|ST1|ST2|ST3|ST4|ST5|ST6|ST7))+((?:&<#INTEGER1&>(+|-)?d+)|$(?:&<#CHARA1&>.)|w$(?:&<#CHARW1&>.)|(?:&<#NAME1&>w[a-zA-Z0-9_]*))|(?:&<#INDEX1&>(AL|AH|CL|CH|DL|DH|BL|BH|AX|CX|DX|BX|SI|DI|SP|BP|EAX|ECX|EDX|EBX|ESI|EDI|ESP|EBP|ST0|ST1|ST2|ST3|ST4|ST5|ST6|ST7))*(?:&<#SCALE1&>[1248])+((?:&<#INTEGER1&>(+|-)?d+)|$(?:&<#CHARA1&>.)|w$(?:&<#CHARW1&>.)|(?:&<#NAME1&>w[a-zA-Z0-9_]*))|(?:&<#INDEX1&>(AL|AH|CL|CH|DL|DH|BL|BH|AX|CX|DX|BX|SI|DI|SP|BP|EAX|ECX|EDX|EBX|ESI|EDI|ESP|EBP|ST0|ST1|ST2|ST3|ST4|ST5|ST6|ST7))*(?:&<#SCALE1&>[1248])+(?:&<#BASE1&>(AL|AH|CL|CH|DL|DH|BL|BH|AX|CX|DX|BX|SI|DI|SP|BP|EAX|ECX|EDX|EBX|ESI|EDI|ESP|EBP|ST0|ST1|ST2|ST3|ST4|ST5|ST6|ST7))+((?:&<#INTEGER1&>(+|-)?d+)|$(?:&<#CHARA1&>.)|w$(?:&<#CHARW1&>.)|(?:&<#NAME1&>w[a-zA-Z0-9_]*)))])|((?:&<#INTTYPE1&>(?:int8|int16|int32|fp32|fp64))s+((?:&<#INTEGER1&>(+|-)?d+)|$(?:&<#CHARA1&>.)|w$(?:&<#CHARW1&>.)|(?:&<#NAME1&>w[a-zA-Z0-9_]*)))|((?:&<#LABEL1&>@w[a-zA-Z0-9_]*)))(s*,s*((?:&<#REGISTER2&>(AL|AH|CL|CH|DL|DH|BL|BH|AX|CX|DX|BX|SI|DI|SP|BP|EAX|ECX|EDX|EBX|ESI|EDI|ESP|EBP|ST0|ST1|ST2|ST3|ST4|ST5|ST6|ST7))|((?:&<#PTRTYPE2&>(?:int8|int16|int32|fp32|fp64))s+[((?:&<#BASE2&>(AL|AH|CL|CH|DL|DH|BL|BH|AX|CX|DX|BX|SI|DI|SP|BP|EAX|ECX|EDX|EBX|ESI|EDI|ESP|EBP|ST0|ST1|ST2|ST3|ST4|ST5|ST6|ST7))|(?:&<#INDEX2&>(AL|AH|CL|CH|DL|DH|BL|BH|AX|CX|DX|BX|SI|DI|SP|BP|EAX|ECX|EDX|EBX|ESI|EDI|ESP|EBP|ST0|ST1|ST2|ST3|ST4|ST5|ST6|ST7))*(?:&<#SCALE2&>[1248])|(?:&<#INDEX2&>(AL|AH|CL|CH|DL|DH|BL|BH|AX|CX|DX|BX|SI|DI|SP|BP|EAX|ECX|EDX|EBX|ESI|EDI|ESP|EBP|ST0|ST1|ST2|ST3|ST4|ST5|ST6|ST7))*(?:&<#SCALE2&>[1248])+(?:&<#BASE2&>(AL|AH|CL|CH|DL|DH|BL|BH|AX|CX|DX|BX|SI|DI|SP|BP|EAX|ECX|EDX|EBX|ESI|EDI|ESP|EBP|ST0|ST1|ST2|ST3|ST4|ST5|ST6|ST7))|((?:&<#INTEGER2&>(+|-)?d+)|$(?:&<#CHARA2&>.)|w$(?:&<#CHARW2&>.)|(?:&<#NAME2&>w[a-zA-Z0-9_]*))|(?:&<#BASE2&>(AL|AH|CL|CH|DL|DH|BL|BH|AX|CX|DX|BX|SI|DI|SP|BP|EAX|ECX|EDX|EBX|ESI|EDI|ESP|EBP|ST0|ST1|ST2|ST3|ST4|ST5|ST6|ST7))+((?:&<#INTEGER2&>(+|-)?d+)|$(?:&<#CHARA2&>.)|w$(?:&<#CHARW2&>.)|(?:&<#NAME2&>w[a-zA-Z0-9_]*))|(?:&<#INDEX2&>(AL|AH|CL|CH|DL|DH|BL|BH|AX|CX|DX|BX|SI|DI|SP|BP|EAX|ECX|EDX|EBX|ESI|EDI|ESP|EBP|ST0|ST1|ST2|ST3|ST4|ST5|ST6|ST7))*(?:&<#SCALE2&>[1248])+((?:&<#INTEGER2&>(+|-)?d+)|$(?:&<#CHARA2&>.)|w$(?:&<#CHARW2&>.)|(?:&<#NAME2&>w[a-zA-Z0-9_]*))|(?:&<#INDEX2&>(AL|AH|CL|CH|DL|DH|BL|BH|AX|CX|DX|BX|SI|DI|SP|BP|EAX|ECX|EDX|EBX|ESI|EDI|ESP|EBP|ST0|ST1|ST2|ST3|ST4|ST5|ST6|ST7))*(?:&<#SCALE2&>[1248])+(?:&<#BASE2&>(AL|AH|CL|CH|DL|DH|BL|BH|AX|CX|DX|BX|SI|DI|SP|BP|EAX|ECX|EDX|EBX|ESI|EDI|ESP|EBP|ST0|ST1|ST2|ST3|ST4|ST5|ST6|ST7))+((?:&<#INTEGER2&>(+|-)?d+)|$(?:&<#CHARA2&>.)|w$(?:&<#CHARW2&>.)|(?:&<#NAME2&>w[a-zA-Z0-9_]*)))])|((?:&<#INTTYPE2&>(?:int8|int16|int32|fp32|fp64))s+((?:&<#INTEGER2&>(+|-)?d+)|$(?:&<#CHARA2&>.)|w$(?:&<#CHARW2&>.)|(?:&<#NAME2&>w[a-zA-Z0-9_]*)))|((?:&<#LABEL2&>@w[a-zA-Z0-9_]*)))(s*,s*((?:&<#REGISTER3&>(AL|AH|CL|CH|DL|DH|BL|BH|AX|CX|DX|BX|SI|DI|SP|BP|EAX|ECX|EDX|EBX|ESI|EDI|ESP|EBP|ST0|ST1|ST2|ST3|ST4|ST5|ST6|ST7))|((?:&<#PTRTYPE3&>(?:int8|int16|int32|fp32|fp64))s+[((?:&<#BASE3&>(AL|AH|CL|CH|DL|DH|BL|BH|AX|CX|DX|BX|SI|DI|SP|BP|EAX|ECX|EDX|EBX|ESI|EDI|ESP|EBP|ST0|ST1|ST2|ST3|ST4|ST5|ST6|ST7))|(?:&<#INDEX3&>(AL|AH|CL|CH|DL|DH|BL|BH|AX|CX|DX|BX|SI|DI|SP|BP|EAX|ECX|EDX|EBX|ESI|EDI|ESP|EBP|ST0|ST1|ST2|ST3|ST4|ST5|ST6|ST7))*(?:&<#SCALE3&>[1248])|(?:&<#INDEX3&>(AL|AH|CL|CH|DL|DH|BL|BH|AX|CX|DX|BX|SI|DI|SP|BP|EAX|ECX|EDX|EBX|ESI|EDI|ESP|EBP|ST0|ST1|ST2|ST3|ST4|ST5|ST6|ST7))*(?:&<#SCALE3&>[1248])+(?:&<#BASE3&>(AL|AH|CL|CH|DL|DH|BL|BH|AX|CX|DX|BX|SI|DI|SP|BP|EAX|ECX|EDX|EBX|ESI|EDI|ESP|EBP|ST0|ST1|ST2|ST3|ST4|ST5|ST6|ST7))|((?:&<#INTEGER3&>(+|-)?d+)|$(?:&<#CHARA3&>.)|w$(?:&<#CHARW3&>.)|(?:&<#NAME3&>w[a-zA-Z0-9_]*))|(?:&<#BASE3&>(AL|AH|CL|CH|DL|DH|BL|BH|AX|CX|DX|BX|SI|DI|SP|BP|EAX|ECX|EDX|EBX|ESI|EDI|ESP|EBP|ST0|ST1|ST2|ST3|ST4|ST5|ST6|ST7))+((?:&<#INTEGER3&>(+|-)?d+)|$(?:&<#CHARA3&>.)|w$(?:&<#CHARW3&>.)|(?:&<#NAME3&>w[a-zA-Z0-9_]*))|(?:&<#INDEX3&>(AL|AH|CL|CH|DL|DH|BL|BH|AX|CX|DX|BX|SI|DI|SP|BP|EAX|ECX|EDX|EBX|ESI|EDI|ESP|EBP|ST0|ST1|ST2|ST3|ST4|ST5|ST6|ST7))*(?:&<#SCALE3&>[1248])+((?:&<#INTEGER3&>(+|-)?d+)|$(?:&<#CHARA3&>.)|w$(?:&<#CHARW3&>.)|(?:&<#NAME3&>w[a-zA-Z0-9_]*))|(?:&<#INDEX3&>(AL|AH|CL|CH|DL|DH|BL|BH|AX|CX|DX|BX|SI|DI|SP|BP|EAX|ECX|EDX|EBX|ESI|EDI|ESP|EBP|ST0|ST1|ST2|ST3|ST4|ST5|ST6|ST7))*(?:&<#SCALE3&>[1248])+(?:&<#BASE3&>(AL|AH|CL|CH|DL|DH|BL|BH|AX|CX|DX|BX|SI|DI|SP|BP|EAX|ECX|EDX|EBX|ESI|EDI|ESP|EBP|ST0|ST1|ST2|ST3|ST4|ST5|ST6|ST7))+((?:&<#INTEGER3&>(+|-)?d+)|$(?:&<#CHARA3&>.)|w$(?:&<#CHARW3&>.)|(?:&<#NAME3&>w[a-zA-Z0-9_]*)))])|((?:&<#INTTYPE3&>(?:int8|int16|int32|fp32|fp64))s+((?:&<#INTEGER3&>(+|-)?d+)|$(?:&<#CHARA3&>.)|w$(?:&<#CHARW3&>.)|(?:&<#NAME3&>w[a-zA-Z0-9_]*)))|((?:&<#LABEL3&>@w[a-zA-Z0-9_]*))))?)?)?)?

(VCZH寫過的正則... ...)


先問是不是,再問為什麼。

應用正則表達式是個很普遍的事情。

流行的 URL 路由都支持正則表達式(Nginx、Express、ThinkPHP...)、流行的文本編輯器也都支持正則表達式搜索(Eclipse、Sublime Text、Web Storm...)

不知道題主的「大家都不喜歡」的結論從哪來的?

你不能駕馭它並不代表它沒用,也不代表都不喜歡。


因為不懂。


沒有見過不喜歡用正則表達式的 只見過不分情況亂用正則的 比如有的時候明明字元串截取更快一些 但是非得用正則提取 就不清楚其目的是什麼了..

當然 開發過程中掌握正則的確很重要 比如 想按照某個模式看下某個文檔的內容 但是不一定要寫到程序里啊


正則表達式學會了是利器。

1. 首先對程序中的字元段的判斷肯定是很有必要的,吃飯的傢伙。

2. 如果你經常編輯大片大片的文本,用支持正則的編輯器,我在說Sublime么?速度飛快。生成代碼也是可以的。

3. linux大戶要是不動點正則,你要用眼睛去看日誌么?

嚯嚯


正則只適合於處理簡單的邏輯,比如配置webpack的test語句,

複雜的東西用正則,debug或者改需求分分鐘讓你歇菜。

所以說刀是好刀,但是瑞士軍刀上角斗場那是自找不痛快。

並不是說不喜歡用,而是場景不夠簡單,不優先選擇正則

畢竟正則的維護成本比一般代碼可是高多了。

推薦 @劉賀 老師的一篇文章,看看他是怎麼噴濫用正則的:

複雜的不要寫簡單:http://zhuanlan.zhihu.com/p/20682805?refer=shanhu

(知乎這個編輯器啊,bullshit!)


許多語言實現的正則表達式語法會有差異。非常不爽。


我為啥不用?正則用起來超級爽~

別和我說爬蟲python就用bs4...java啥的就用jsop...

另外,正則很爽啊,處理各種文本啊文本啊~~~百度還有入門文章


喜歡用,但是不喜歡讀。


————————————2016.04.26更新完畢分割線——————————————

這個問題收到了一些評論,我再更新下我對正則的一些想法。

我個人覺得寫正則一個重要的方法就是 化繁為簡, 如何化繁為簡呢?要記住不要讓正則搞定一切。

案例1:我前面看到過有人問把一段文本當中3的倍數找出來,正則怎麼寫?直接寫正則直接搞定,肯定很難。我們可以簡化:

1) 用正則表達式 /d+/ 匹配出文本中的數字字元串

2)用parseInt或者Number函數,把數字字元串轉換成數字

3) 判斷數字是否是3的倍數

案例1中我們只要了一個很簡單的正則/d+/。這個案例說明:正則表達式干字元串匹配的事,數字的事讓數字來干。

案例2:用一個正則表達式匹配ip地址,如果用一個正則寫能搞定,但是很長,很難懂,且容易出錯,大家可以網上搜下。我們可以簡化:

1)用/^(d+).(d+).(d+).(d+)$/ 匹配出四個數字字元串(如果沒有4個數字字元串當然不是ip了)

2)對於每個數字字元串: a) 用/^0d+$/排除類似"001"的情況。b)用parseInt或者Number函數,把數字字元串轉換成數字,看這個數字是否在0-255之間。

案例2中,我們用了兩個簡單的正則 /^(d+).(d+).(d+).(d+)$/ 、 /^0d+$/。這個案例說明,我們並不一定只用一次正則,再次說明數字的事情數字干。

儘管兩個案例的解決方案,比用一個複雜的正則搞定,代碼量大。但有時候代碼的簡單易讀易學習,比代碼量的節約,更重要。

————————————2016.04.26更新完畢分割線——————————————

以前在論壇裡面有人文正則問題,我給的一個回答,有一個例子,根據需求不斷升級,不斷優化一個正則表達式。當時反饋還不錯,看看對題主有沒有用。

1. 正則表達式 /phone/ 表示包含"phone"字元串,那麼 /phone/.test("My phone number is 13111456788") 當然返回true, 因為 "My phone number is 13111456788"字元串中包含"phone"字元串。

2. 現在我要把 "My phone number is 13111456788" 中的手機號碼替換成 "就不告訴你" 我當然可以這麼做 "My phone number is 13111456788" .replace(/13111456788/, "就不告訴你"); 當然返回 "My phone number is 就不告訴你"

3. 對於一個有逼格的程序員,上面的實現方式明顯太low了,如果字元串中出現的是其他手機號碼而不是"13111456788",作為一個有逼格的程序員至少也要搞出能替換所有手機號碼的程序嘛,於是我們需要一個牛B的東西叫做 字元類,故名思議它能表示一類字元,比如[0-9](字元類的語法是[字元類包含的字元])表示數字,使用字元類我們升級下逼格: "My phone number is 13111456788" .replace(/[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]/, "就不告訴你");

4. [0-9]有5個字元,寫起來不爽,我們引入元字元,元字元是預定義的特殊字元,其中 d 表示數字等價於[0-9],使用元字元我們再升級下逼格: "My phone number is 13111456788" .replace(/ddddddddddd/, "就不告訴你");

5. 什麼我們的代碼中出現了11個d, 碼農教義第一條 Don"t Repeat Yourself ,你都不知道嘛。為了進一步提升逼格,我們需要另個一牛B的東西叫做量詞,顧名思義是表示數量,使用量詞{11}(表示出現11次)我們又升級下逼格: "My phone number is 13111456788" .replace(/d{11}/, "就不告訴你");

6. 假如我有兩個電話號碼,"My phone number is 13111456788 and 13563546782" 那麼 "My phone number is 13111456788 and 13563546782" .replace(/d{11}/, "就不告訴你"); 運行結果為: "My phone number is 就不告訴你 and 13563546782"。 啊,我想都不告訴你們,怎麼還告訴你們 13563546782,我的粉絲不是要打爆我的電話了。這個時候我們需要另一個牛B的東西修飾符,我們使用 g (表示所有匹配的字元串),使用修飾符我們升級下逼格: "My phone number is 13111456788 and 13563546782" .replace(/d{11}/g, "就不告訴你");


正則表達式還是很強大的,從簡單的到複雜的,逐漸就學會了


雖然犀利,但是不得不承認,這玩意可讀性太差了。

自己寫的複雜一點的正則表達式,過一段時間之後,就讀不懂了.

要搞懂,就必須重新構造一遍.......

所以,不愛用。


「先問是不是,再問為什麼。」

推薦一個在線正則測試工具 New Fiddle


更新:

前幾天完成了最新版本,基於Win10 UWP的,已經包含了前兩個版本的主要功能,算是比較全面而實用了,依然完全免費無廣告,Windows商店鏈接:SkyD Regex

————————————————————————

不是吧,為什麼會有人不喜歡用正則?效率這麼高,我基本上每次編程都要用到啊。

莫非你們用的工具太渣渣?

我這裡安利一下我自己開發的正則工具好了,真的很強大很方便啊:

這是目前最新版的,主打新功能有兩點:

  • 支持無限層級的複雜多重匹配與替換
  • 支持在替換時以$@符號引用經過處理後的組內容

這兩個功能主要為了解決如下問題:

  1. 冗長的表達式結構。

    在匹配複雜的格式時,使用的表達式不僅冗長,且晦澀如天書,一旦修改時不小心改變了某個符號後患無窮。

    無限級多重替換功能將極大改善這一情況,你可以將替換工作拆分成若干個步驟,分別處理,使得思路清晰,表達式易於維護。
  2. 不可能的任務。

    正則表達式是萬能的,但萬這個數字並不大,有很多格式是不可能或很難用一個表達式來完成的,很多時候我們需要自己來寫一個新程序予以解決,而當有了$@引用功能,很多問題迎刃而解。

    $@符號允許引用目標組的處理結果,比如以前我們在替換時以$1形式引用組1的內容,現在我們可以對$1組再進行正則替換,然後以$@1形式引用其替換結果,這在處理複雜格式時極為有用。

使用入門

首先在源文本框中輸入要處理的字元,通常通過剪切板粘貼入:

然後輸入表達式及匹配選項:

再輸入替代內容及替代選項:

單擊執行替換按鈕:

此時匹配項和結果都將出現在左欄,展開以查看:

此時在右側你可以通過集合記錄導航功能查看具有多個結果的節點:

此時你可以繼續對任意節點進行正則替換操作,以達成需求。

全部處理完畢後,點擊複製最終輸出結果按鈕可以複製最下面的OutPutText節點文本到剪切板:

通過導入導出功能可以讀取和保存所有數據:

特別提示

這裡形如$0或${FuncName}或$@{Parameters}的名稱即是在替換時的引用標記,上述三個形式分別代表組、命名組和經過處理的命名組,替換時可以以$形式引用子級節點內容,或以$@形式引用孫級節點內容。

當前所選節點能夠引用的後代節點都使用淺黃色表示。

後面的[105]表示該組有105個項,可以通過滑動導航條查看每一項:

小技巧

點選任意一個$開頭的節點後,按Ctrl+C可以直接複製其替換時的引用字元到剪切板:

除此之外,還有個更方便的辦法,就是直接在$開頭的節點上點滑鼠右鍵,即可直接將其引用字元複製到剪切板:

如果引用孫級節點的處理結果還不能滿足你的話,你還可以繼續對其進行處理,每多一層處理,引用時就多些一個@:

這樣你的表達式可以像樹杈一樣不斷延展,但始終都不脫離主幹。

更詳細的教程看這一篇文章:RegeX 3 正則表達式實踐教程之 —— 在Eclipse中以裝飾器模式包裝介面

RegeX3是基於Silverlight的,可以安裝到本機離線使用,請訪問這個使用或下載:

RegeX 3 正則表達式替換器 (Silverlight版)

提示:程序中單擊右鍵可以安裝到桌面,並脫離瀏覽器運行:

——————————————————————————————————

對於表達式還不算特別熟悉的朋友,還可以下載早先的版本,舊版本的可視化效果更好,有助於你理解和分析匹配項,而且是完全本地運行的:

下載頁面:RegeX —— 可視化正則表達式替換器

舊版本的教程:RegeX使用教程


推薦閱讀:

前端開發工程師都能做什麼?
js為什麼叫js?
中等規模的網站管理後台用什麼js框架好呢?
Bootstrap 3 有哪些改進?
因為什麼原因你開始從事web前端開發?

TAG:JavaScript | PHP | Java | 正則表達式 | C# |