日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

JS理解正则表达式

發(fā)布時(shí)間:2023/12/2 综合教程 44 生活家
生活随笔 收集整理的這篇文章主要介紹了 JS理解正则表达式 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

原文:理解正則表達(dá)式

在我初學(xué)正則表達(dá)式的時(shí)候,走了一些彎路,強(qiáng)行記憶了很多符號和用法。

等到我有更深入的理解的時(shí)候我發(fā)現(xiàn),從翻譯和概念的角度上切入,學(xué)習(xí)起來會順暢得多。

本文以JavaScript里的正則表達(dá)式為例,講解其中的關(guān)鍵要素。希望能幫助到初學(xué)者。

注:也只限于闡述關(guān)鍵要素,不會事無巨細(xì)地展開。

何為正則表達(dá)式?

在中文語境里,「正則」兩個字有點(diǎn)讓人發(fā)怵,仿佛高深數(shù)學(xué)或物理中的「正則化」和「歸一化」,抽象而難懂。

其實(shí)放到英文里,它是regular expression,而regular有「規(guī)律、規(guī)范、整齊、合格、正規(guī)」等意味,「正則」只是其中一種翻譯。

不把它翻譯成一個詞組,而翻譯成一句話,大致是:表達(dá)規(guī)范和規(guī)則的句子。

這里的規(guī)范和規(guī)則,指的是一個字符串的形式規(guī)則。

至于JavaScript里的 RegExp 構(gòu)造函數(shù),是Regular Expression的前三個字母縮寫。

正則表達(dá)式的格式

JavaScript里,正則表達(dá)式有兩個構(gòu)造方式,一個是通過RegExp這個構(gòu)造函數(shù)創(chuàng)建實(shí)例,另一個是正則表達(dá)式字面量寫法。

var regexp1 = new RegExp('hello regular expression')
var regexp2 = /hello regular expression/

// test 方法,測試給定的字符串是否符合正則表達(dá)式所描述的字符串格式
regexp1.test('hello regular expression') // -> true
regexp1.test('hello word') // -> false

// exec 方法,是 execute 這個單詞的縮寫,「執(zhí)行」。返回給定的字符串中符合「正則表達(dá)式所描述的字符串格式」的部分
regexp2.exec('hello regular expression') //  返回 'hello regular expression'
regexp2.exec('hello regular expression, more words') //  只返回 'hello regular expression',其它部分不匹配

正則表達(dá)式里的元字符

元字符聽起來也很抽象,其實(shí)換個例子就容易理解:學(xué)習(xí)如何學(xué)習(xí),叫元學(xué)習(xí);關(guān)于知識的知識,叫元知識。

元字符,則是描述字符的字符,比如,數(shù)字,字母,空格,換行等。

元編程,就是能生成代碼的代碼,在 Javascript 構(gòu)造符合語法的字符串,放到eval(code)里運(yùn)行一下,你就在元編程了。

然后看看元字符、元編程的英文:meta-charactermeta-programming,對 meta 長個記性,怯魅。

列舉幾個元字符。元字符大多以反斜杠開頭 ,因?yàn)榍懊嬲故镜摹刚齽t表達(dá)式字面量」寫法里,用的是兩個斜杠包裹,所以得用反斜杠或其他標(biāo)識符。

  • d,匹配單個數(shù)字;d 是 digit 這個單詞的縮寫,它的中文意思就是「數(shù)字」
  • w,匹配單個單詞字符,w 是 word 的縮寫,就是字母 a-z,數(shù)字 0-9,不包括逗號、句號、加減乘除號、括號等。
  • s,匹配單個空白字符,s 是 space 的縮寫,就是空白的意思。
  • n,匹配換行符,n 是 newline 的縮寫,中文就是換行。
  • r,匹配回車符,r 就是 return 的縮寫,回車在這里就是它的中文意思。
  • t,匹配制表符,就是 tab 鍵打出來的一串用以縮進(jìn)的空白字符,tab 是 tabel 的縮寫,table 就有表格和制表的意思。
  • b,匹配單詞邊界,b 是 boundary 的縮寫,中文就是邊界的意思。

如你所見,所謂的元字符,就是反斜杠加單詞縮寫,來表征某個字符類型。這就是它們的設(shè)計(jì)原則。

正則表達(dá)式里的量詞

元字符大多只能表示單個字符的類型。

我們還需要量詞,以表示「有,有0到多個,有至少一個,有n個以上,有n到m個,以某個字符開頭,以某個字符結(jié)尾等」。

這時(shí)你可以停下來,稍作思考,讓你來設(shè)計(jì),你會設(shè)計(jì)成什么樣?

Javascript的設(shè)計(jì)如下:

  • n+,至少1個 n 類型的字符
  • n*,0到多個 n 類型的字符
  • n?,0 或 1 個 n 類型的字符
  • n{X},X 個 n 類型的字符
  • n{X,Y},X 到 Y 個 n 類型的字符
  • n{X,},至少 X 個 n 類型的字符
  • n$,以 n 類型的字符結(jié)尾
  • ^n,以 n 類型的字符開頭

如你所見,大致是一些類似數(shù)學(xué)里表達(dá)區(qū)間的意思。

正則表達(dá)式里的表達(dá)式

你可以戲謔地說它是「元表達(dá)式」。

其實(shí),它們也是描述范圍的,只是不是所有范圍都是關(guān)于某個字符類型n 的數(shù)量和出現(xiàn)位置,有些范圍跟多個字符組成的集合有關(guān)。

比如,在這幾個字符類型之內(nèi),在這幾個字符類型之外的,便利地表示 26 個字母,便利地表示 10 個數(shù)字字符。

Javascript的設(shè)計(jì)如下:

  • [abc],匹配單個字符,它是abc的集合的元素
  • [^abc],匹配單個字符,它不是abc的集合的元素
  • [0-9],匹配單個字符,它是從0到9這個集合的元素
  • [a-z],匹配單個字符,它是26 字母這個集合的元素
  • (red|blue|green),匹配多個連續(xù)字符,它是 red blue green 這三個詞的集合的元素

小試牛刀

匹配一個電話號碼,形式如 020-88813243。

簡單版本,(開頭)三個數(shù)字+一個橫杠+八個數(shù)字(結(jié)尾),就是/^d{3}-d{8}$/

需求變化,只匹配 020 開頭的電話號碼,就是/^020-d{8}$/

需求變化,支持分機(jī),分機(jī)為 5 個數(shù)字,加后綴,就是/^020-d{8}-d{5}$/

需求變化,電話號碼可以是7個,用區(qū)間量詞,就是/^020-d{7,8}-d{5}$/

需求變化,有可能沒有分機(jī),用區(qū)間量詞,中括號包裹住分機(jī)為一組,后面加個問號,表示0或多個,就是/^020-d{7,8}(-d{5})?$/

需求變化,區(qū)隔符可能是橫杠,也可能是星號或空格,用集合表達(dá)式,就是/^020[-*s]d{7,8}([-*s]d{5})?$/

結(jié)語

在我們理解了正則表達(dá)式的概念和設(shè)計(jì)思路之后,剩下的,就是查文檔和尋找模式的工作了。

實(shí)在有難題,網(wǎng)上也可以搜索到現(xiàn)成的堅(jiān)實(shí)的正則表達(dá)式可用。這里面的門道還是很多的,在此我們?nèi)雮€門,打個基礎(chǔ)即可。

補(bǔ)充:正則表達(dá)式簡要學(xué)習(xí)

元字符

元字符是功能性的匹配符號, 如:
b 單詞的開頭或結(jié)尾,也就是單詞的分界處
* 匹配任意數(shù)量的字符
. 匹配除了換行之外的所有字符
d 匹配0到9單個數(shù)字
s 匹配任意的空白符,包括空格,制表符(Tab),換行符,中文全角空格等
w匹配 字母 或 數(shù)字 或 下劃線 或 漢字 等
^ 匹配字符串的開始
$ 匹配字符串的結(jié)束

字符轉(zhuǎn)意

查找元字符本身的話,比如你查找.,或者*,就出現(xiàn)了問題:你沒辦法指定它們,因?yàn)樗鼈儠唤忉尦蓜e的意思。這時(shí)你就得使用來取消這些字符的特殊意義。因此,你應(yīng)該使用.*。當(dāng)然,要查找本身,你也得用\

字符類

[ ] 集合查找 ,比如 [abcde] 表示匹配里面包含的字符 , 常見的[0-9]d等價(jià), 即匹配一位數(shù)字, [a-z0-9A-Z_]也完全等同于w(如果只考慮英文的話)
(?0d{2}[) -]?d{8}首先是一個轉(zhuǎn)義字符(,它能出現(xiàn)0次或1次?,然后是一個0,后面跟著2個數(shù)字d{2},然后是)-空格中的一個,它出現(xiàn)0次或1次?,最后是8個數(shù)字d{8}

分枝條件

上面那個表達(dá)式也能匹配010)12345678或(022-87654321這樣的“不正確”的格式。
正則表達(dá)式里的分枝條件指的是有幾種規(guī)則,如果滿足其中任意一種規(guī)則都應(yīng)該當(dāng)成匹配,具體方法是用|把不同的規(guī)則分隔開。
0d{2}-d{8}|0d{3}-d{7}表示0開頭接兩位數(shù)字,-后面連著8位數(shù)的電話號碼,比如020-12345678 或者 0開頭接三位數(shù)字,-后面連著7位數(shù)的電話號碼,比如0751-1234567
使用分枝條件時(shí),要注意各個條件的順序。原因是匹配分枝條件時(shí),將會從左到右地測試每個條件,如果滿足了某個分枝的話,就不會去再管其它的條件了。

分組

如果想要重復(fù)多個字符又,你可以用小括號來指定子表達(dá)式(也叫做分組)
(d{1,3}.){3}d{1,3}是一個簡單的IP地址匹配表達(dá)式。要理解這個表達(dá)式,請按下列順序分析它:d{1,3}匹配1到3位的數(shù)字,(d{1,3}.){3}匹配三位數(shù)字加上一個英文句號(這個整體也就是這個分組)重復(fù)3次,最后再加上一個一到三位的數(shù)字(d{1,3})
正則表達(dá)式中并不提供關(guān)于數(shù)學(xué)的任何功能,所以只能使用冗長的分組,選擇,字符類來描述一個正確的IP地址:((2[0-4]d|25[0-5]|[01]?dd?).){3}(2[0-4]d|25[0-5]|[01]?dd?)

反義

有時(shí)需要查找不屬于某個能簡單定義的字符類的字符。比如想查找除了數(shù)字以外,其它任意字符都行的情況,這時(shí)需要用到反義:

符號 表示
W 匹配任意不是字母,數(shù)字,下劃線,漢字的字符
S 匹配任意不是空白符的字符
D 匹配任意非數(shù)字的字符
B 匹配不是單詞開頭或結(jié)束的位置
[ ^x ] 匹配除了x以外的任意字符
[ ^aeiou ] 匹配除了aeiou這幾個字母以外的任意字符

例子:
S+匹配不包含空白符的字符串。
<a[^>]+>匹配用尖括號括起來的以a開頭的字符串

貪婪與懶惰

當(dāng)正則表達(dá)式中包含能接受重復(fù)的限定符時(shí),通常的行為是(在使整個表達(dá)式能得到匹配的前提下)匹配盡可能多的字符。以這個表達(dá)式為例:a.*b,它將會匹配最長的以a開始,以b結(jié)束的字符串。如果用它來搜索aabab的話,它會匹配整個字符串aabab。這被稱為貪婪匹配。
有時(shí),我們更需要懶惰匹配,也就是匹配盡可能少的字符。前面給出的限定符都可以被轉(zhuǎn)化為懶惰匹配模式,只要在它后面加上一個問號?。這樣.*?就意味著匹配任意數(shù)量的重復(fù),但是在能使整個匹配成功的前提下使用最少的重復(fù)。
a.*?b匹配最短的,以a開始,以b結(jié)束的字符串。如果把它應(yīng)用于aabab的話,它會匹配aab(第一到第三個字符)和ab(第四到第五個字符)
為什么第一個匹配是aab(第一到第三個字符)而不是ab(第二到第三個字符)?簡單地說,因?yàn)檎齽t表達(dá)式有另一條規(guī)則,比懶惰/貪婪規(guī)則的優(yōu)先級更高:最先開始的匹配擁有最高的優(yōu)先權(quán)

符號 表示
*? 重復(fù)任意次,但盡可能少重復(fù)
+? 重復(fù)1次或更多次,但盡可能少重復(fù)
?? 重復(fù)0次或1次,但盡可能少重復(fù)
{n,m}? 重復(fù)n到m次,但盡可能少重復(fù)
{n,}? 重復(fù)n次以上,但盡可能少重復(fù)

參考: http://deerchao.net/tutorials/regex/regex.htm

總結(jié)

以上是生活随笔為你收集整理的JS理解正则表达式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。