首頁  >  文章  >  web前端  >  正規表示式基礎簡介與學習實例

正規表示式基礎簡介與學習實例

零下一度
零下一度原創
2017-06-26 13:41:06937瀏覽

經常碰到需要使用正則表達式的情況,總是習慣性地搜索,複製,粘貼,時間久了導致原來還知道一點正則表達式的自己,現在連讀一個複雜的表達式都有困難。因此,決定,好好學學正規表示式,這裡先從基礎開始,在記錄幾個常見的表達式,練習讀正規表示式的能力,另外簡單介紹一下JavaScript中的regexp物件。

一、正規表示式簡介:

正規表示式:是由普通字元以及特殊字元組成的文字模式,它描述了字串匹配的規則,可以用來檢查字串是否包含某個子字串,將某個字串替換或從字串中提取出某個子字串。建構正規表示式和數學表達式一樣,可以將小的表達式組合來建構更大的表達式。

普通字符:普通字符包括沒有顯示指定為元字符的所有可打印和不可打印字符,這包括所有大寫和小寫字母,所有數字,所有標點符號和一些其他符號。

 符合x指明的控製字元。例如 \cM 符合一個 Control-M 或回車符。 x 的值必須為 A-Z 或 a-z 之一。否則,將 c 視為一個原義的 'c' 字元。  符合一個換頁符號。等價於 \x0c 和 \cL。  符合一個換行符號。等價於 \x0a 和 \cJ。  符合一個回車符。等價於 \x0d 和 \cM。  符合任何空白字符,包括空格、製表符、換頁符等等。等價於 [ \f\n\r\t\v]。  符合任何非空白字元。等價於 [^ \f\n\r\t\v] 符合一個製表符。等價於 \x09 和 \cI  符合一個垂直製表符。等價於\x0b 和\cK
非列印字元
非列印字元 說明
##\cx
\f
\n
\r
\s
\S
\t
\v

特殊字符:一些有特殊含義的字符,如通配符“*”,這些字符如果要在字串中尋找需要使用轉義字符,也就是反斜線\。 通配符# 描述 () * + . [ ? \^{|
 特殊字元
 $
##匹配輸入字串的結尾位置。
 標記一個子運算式的開始和結束。
 符合前面子運算式零次或多次。
 符合前面的子表達式一次或多次。
 符合除換行符號\n以外的任何單字元。
 標記一個中括號表達式的開始。
 符合前面的子表達式一次或零次或指明一個非貪婪限定符。
 將下一個字元標記為特殊字元、或元義字元、或向後引用、或八進位轉義符。
 符合輸入字串的起始位置,除非在方括號表達式中使用,此時它表示不接受該字元集合。
 標記限定符表達式的開始。
 指示兩項之間的一個選擇。 ############

限定符:限定符用來指定正規表示式的一個給定元件必須要出現多少次才能滿足符合次數不固定,主要包括{0 or 1},{1 or n} ,{0 或 1},{n},{大於等於n},{大於等於n,小於等於m}六種。對應表達式分別是*,+,? ,{n},{n,},{n,m}。

##* #符合前面的子表達式零次或多次。 +符合前面的表達式一次或多次。 ? 符合前面的子表達式零次或一次。 {n}n是一個非負整數,符合確定的n次。 {n,}n是一個非負整數,至少符合n次。 {n,m}m,n是非負整數,n<=m,最少符合n次,最多符合m次。注意在“,”和兩個數之間不能有空格。
限定符
限定符 #描述

定位符: 定位符號能夠使我們將正規表示式固定到行首或行尾。同時也可以建立特殊的表達式,例如:正規表示式出現在一個單字內或一個單字開頭或一個但多次結尾。定位符用來描述字串或單字的邊界。

定位符號字元描述#匹配輸入字串的開始位置。如果設定RegExp為Multiline屬性,也可以與\n和\r之後的位置相符。 符合輸入字串結尾的位置。如果設定RegExp為Multiline屬性,也可以與\n和\r之後的位置相符。 符合一個字邊界,即字與空格間的位置。 非字邊界符合。
$
\b
\B
######

注意:限定符不能與定位點一起使用,由於在靠近換行或字邊界的前面或後面不能有一個以上的位置,因此不允許「^*之類的表達式」。

若要符合一行文本開始處的文本,應該將^置於正規表示式開始;若要符合一行文本結尾處的文本,則在正規表示式的結尾處使用$。不要將 ^ 或$的這種用法與中括號表達式內的用法混為一談。

eg:

/^Chapter [1-9][0-9]{0,1}/符合章節標題為兩位數的以Chapter開頭的標題;

/^Chapter [1-9][0-9]{0,1}$/匹配開始和結尾都為章節標題,也就是說這一行只有章節標題;

/\bCha/匹配字邊界,也就是說以Cha開頭的邊界;

/ter\b/結尾是ter的字。

/\Bapt/,匹配非字邊界,例如chapter中的apt匹配,但是aptitude中的就不匹配;

選擇:用圓括號將所有項目括起來,相鄰的選擇之間用|分隔。但是使用圓括號有一個副作用,是相關的匹配會被緩存,此時可用? :放在第一個選項前來消除這個副作用;

非捕獲元:

? :消除不想要的快取副作用,放在選擇項目的第一個選項之前。
? =正向預查,在任何開始符合圓括號內的正規模式的位置來匹配搜尋字串。
? ! 反向預查,在任何開始不符合該正規模式的位置來符合搜尋字串。

反向引用:(莫名想到了C語言裡面的遞歸。。)我覺得通俗的講,反向引用,就是引用已經被緩存的模式也就是後文中的通過\ n來對緩衝區進行存取。對一個正規表示式模式或部分模式兩邊添加圓括號將導致相關匹配存儲到一個臨時緩衝區中(類似於子串,記得開始時有說過,正則就像數學表達式,由小的簡單的表達式式組合成為大的複雜的表達式,這些臨時緩衝區可以理解為那些小表達式的匹配結果),所捕獲的每個子匹配都按照在表達式中從左到右的順序儲存。緩衝區編號從1開始,最多可儲存99個捕獲的子表達式。每個緩衝區都可用\n來訪問,其中n為一個標識特定緩衝區的一位或二位十進制數。可以使用非捕獲元字元? :,? =,? !來重寫捕獲,忽略對相關匹配的快取。

反向引用最簡單最有用的應用之一,是提供查找文本中兩個相同的相鄰單字的匹配項的能力:

eg1:​​提取相同的單字。

var str=Is this the cost of of gasoline going up up?

var patt1= /\b([a-z]+) \1\b/;

#document.write(str.match(patt1));

#eg2:分割URL,從這個例子好像看出反向引用其實就是引用或者說提取大表達式中的子項,並使用,感覺這個反向引用有點晦澀難懂。 (暫且放在這裡,做個備忘,後期再修改);

var patt1 = /(\w+):\/\/([^/:]+)(:\d*)?([^#]*)/;

######################### #####################

#arr = str# .match(patt1);

#二,正規表示式讀取的練習。

1./chapter [1-9][0-9]/

這個表達式符合chapter +任何整數,例如1、19、109、10099.。 。 。 。

首先前面的chapter是固定,【1-9】也是固定,然後【0-9】被限定符*限定,表示它可以出現零次或多次。因此,可以是空,可以是一位,可以是多位。

2./[a-zA-z]+://[^\s]*/

#符合URL

#3./\d{3}- \d{8}|\d{4}-\{7,8}/

#符合國內電話號碼

4.\[1-9][0-9]{4 ,}\

符合騰訊QQ號碼

5.\[1-9]\d{5}(?!\d)\

符合國內郵遞區號

6.\^(\d{6})(\d{4})(\d{2})(\d{2})(\d{3})([0-9] |X)$\

符合十八位身分證號碼

7.\^[1-9]\d*$\

符合正整數

8.\^-[1-9]\d*\

符合負整數

9.\^-?[1-9]\d*$\

符合整數10.\^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$\

符合正浮點數11.\^-[1-9]\d*\.\d*|-0\.\d*[1-9]\d*$\符合負浮點數

三,JavaScript的RegExp物件

1.建立正規表示式物件

new RegExp(

pattern, attributes

);

pattern參數指涉正規表示式,是字串,attributes是一個可選參數包括g,i,m。分別指全域匹配,區分大小寫和多行匹配。

2.

RegExP物件的屬性

:

global:RegExp物件是否具有標誌m;

eg:if(patt1.global )  {  alert("Global property is set"); };

ignoreCase:RegExp物件是否具有標誌m;laseIndex:一個整數,標誌開始下一次符合的字元位置;

multiline:RegExp物件是否具有標誌m;

source:正規表示式的原始文字。

3.

RegExp物件的方法
######compile###:編譯正規表示式。 ######compile()有兩種用途,第一種是在腳本執行過程中編譯正規表示式。第二種是改變和重新編譯正規表示式;######eg:RegExpObject.compile(regexp,modifier);######第一個參數為正規表示式,第二個參數規定符合型別;######
var str="Every man in the world! Every woman on earth!";

patt=/man/g;
str2=str.replace(patt,"person");
document.write(str2+"<br />");patt=/(wo)?man/g;
patt.compile(patt);//这里改变了正则表达式str2=str.replace(patt,"person");
document.write(str2);###<p><strong>exec</strong>:检索字符串中指定的值,返回找到的值并确定其位置。</p>
<p>eg:RegExpObject.exec(<em>string</em>);//返回一个结果,用于存放匹配的数组,如果未找到匹配,则为null。</p>
<h3>说明:</h3>
<p>exec() 方法的功能非常强大,它是一个通用的方法,而且使用起来也比 test() 方法以及支持正则表达式的 String 对象的方法更为复杂。</p>
<p>如果 exec() 找到了匹配的文本,则返回一个结果数组。否则,返回 null。此数组的第 0 个元素是与正则表达式相匹配的文本,第 1 个元素是与 RegExpObject 的第 1 个子表达式相匹配的文本(如果有的话),第 2 个元素是与 RegExpObject 的第 2 个子表达式相匹配的文本(如果有的话),以此类推。除了数组元素和 length 属性之外,exec() 方法还返回两个属性。index 属性声明的是匹配文本的第一个字符的位置。input 属性则存放的是被检索的字符串 string。在调用非全局的 RegExp 对象的 exec() 方法时,返回的数组与调用方法 String.match() 返回的数组是相同的。</p>
<p>但是,当 RegExpObject 是一个全局正则表达式时,exec() 的行为就稍微复杂一些。它会在 RegExpObject 的 lastIndex 属性指定的字符处开始检索字符串 string。当 exec() 找到了与表达式相匹配的文本时,在匹配后,它将把 RegExpObject 的 lastIndex 属性设置为匹配文本的最后一个字符的下一个位置。这就是说,可以通过反复调用 exec() 方法来遍历字符串中的所有匹配文本。当 exec() 再也找不到匹配的文本时,它将返回 null,并把 lastIndex 属性重置为 0。</p>
<h2>提示和注释</h2>
<p class="important">重要事项:如果在一个字符串中完成了一次模式匹配之后要开始检索新的字符串,就必须手动地把 lastIndex 属性重置为 0。</p>
<p class="tip">提示:请注意,无论 RegExpObject 是否是全局模式,exec() 都会把完整的细节添加到它返回的数组中。这就是 exec() 与 String.match() 的不同之处,后者在全局模式下返回的信息要少得多。因此我们可以这么说,在循环中反复地调用 exec() 方法是唯一一种获得全局模式的完整模式匹配信息的方法。</p>
<div class="cnblogs_code"><pre class="brush:php;toolbar:false">var str = "正则表达式的exec方法测试"; 
var patt = new RegExp("exec","g");var result;while ((result = patt.exec(str)) != null)  {
          document.write('result:'+result);
            document.write("<br />");
            document.write('patt.lastIndex:'+patt.lastIndex);
          }

test:检索字符串中指定的值,返回true或false。

eg:var result = patt1.test(str);

4.支持正则表达式的string对象的方法

search:检索与正则表达式相匹配的值。

stringObj.search(regexp);//参数可以是子串,也可以是regexp对象。

注意:search()方法不执行全局匹配,它将忽略标志g,它同时忽略regexp的lastIndex属性,并且总是从字符串开始进行检索,所以他的返回值始终是sgringObj的第一个匹配的位置。如果要忽略大小写应追加i标记。

document.write(str.search(/abc/i);

match:找到一个或多个正则表达式的匹配。

stringObj.match(searchValue);//参数为要检索的字符串值

stringObj.match(regexp);//要匹配的模式的regexp对象。

返回存放匹配结果的数组。该数组的内容依赖于regexp是否具有全局属性g;

说明

match() 方法将检索字符串 stringObject,以找到一个或多个与 regexp 匹配的文本。这个方法的行为在很大程度上有赖于 regexp 是否具有标志 g。

如果 regexp 没有标志 g,那么 match() 方法就只能在 stringObject 中执行一次匹配。如果没有找到任何匹配的文本, match() 将返回 null。否则,它将返回一个数组,其中存放了与它找到的匹配文本有关的信息。该数组的第 0 个元素存放的是匹配文本,而其余的元素存放的是与正则表达式的子表达式匹配的文本。除了这些常规的数组元素之外,返回的数组还含有两个对象属性。index 属性声明的是匹配文本的起始字符在 stringObject 中的位置,input 属性声明的是对 stringObject 的引用。

如果 regexp 具有标志 g,则 match() 方法将执行全局检索,找到 stringObject 中的所有匹配子字符串。若没有找到任何匹配的子串,则返回 null。如果找到了一个或多个匹配子串,则返回一个数组。不过全局匹配返回的数组的内容与前者大不相同,它的数组元素中存放的是 stringObject 中所有的匹配子串,而且也没有 index 属性或 input 属性。

注意:在全局检索模式下,match() 即不提供与子表达式匹配的文本的信息,也不声明每个匹配子串的位置。如果您需要这些全局检索的信息,可以使用 RegExp.exec()。

eg:document.write(str.match(/\d+/g));

replace:替换与正则表达式匹配的子串。

stringObect.replace(regexp/substr,replacement);

regexp/substr:必须,正则表达式或者自字符串。

replacement):一个字符串值,规定了替换文本或生成替换文本的函数。

返回一个新的字符串,使用replacement替换第一次匹配或者所有匹配之后得到的。注意:指定g全局变量则替换所有的匹配,否则只替换第一次匹配到的字符串。

split:把字符串分割为字符串数组。

stringObect.split(separator,howmany);

separator:必须,字符串或正则表达式,从该参数指定的地方分割字符串;

howmany:可选,指定返回数组的最大长度,若设置了该参数,返回的子串不会多余这个参数指定的数组,如果没有设置该参数,整个字符串都会被分割。

返回一个字符串数组,不包括separator本身。

 

<br><br>

以上是正規表示式基礎簡介與學習實例的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
上一篇:從基礎到精通--javascript語言下一篇:從基礎到精通--javascript語言

相關文章

看更多