前端點滴(JS核心)(四)---- 正則表達式(上)

一、正則表達式(上)

1. 前言

正則表達式基礎:https://blog.csdn.net/Errrl/article/details/103880657

2. 匹配模式

參考blog:https://blog.csdn.net/weixin_42516949/article/details/80858913

// 貪婪: 儘可能多的匹配
// 非貪婪: 儘可能少的匹配

// 語法:將?緊跟在任何量詞 *、 +、? 或 {} 的後面,將會使量詞變爲非貪婪的(匹配儘量少的字符),和缺省使用的貪婪模式(匹配儘可能多的字符)正好相反。

//不加問號默認爲貪婪
var reg =  /a.*c/
var string = 'aaaccaa'
var result = string.match(reg)
console.log(result)  //=> ["aaacc"]
 
//加上問號爲非貪婪
var reg =  /a.*?c/
var string = 'aaaccaa'
var result = string.match(reg)
console.log(result)  //=> ["aaac"]

3. 正則表達式分組/捕獲和反向引用

捕獲和反向引用的語法的解釋:
正則中出現的小括號,就叫捕獲或者分組
在正則語法中(在/…/內),在捕獲的後面,用 “\1” 來引用前面的捕獲。用 “\2” 表示第二個捕獲的內容….
注意: 在正則語法外(如replace時),用 “$1” 來引用前面的捕獲。

    <script>
        var str = '1122 3434 5678 9090 1516';
        // 要求:匹配連續四個數字
        // var res = str.match(/\d{4}/g);
        // var res = str.match(/[0-9]{4}/g);
        // var res = str.match(/\d\d\d\d/g);

        // 捕獲與引用
        // 要求:匹配連續四個數字。要求1,3相同
        // var res = str.match(/(\d)\d\1\d/g);
        // 要求:匹配連續四個數字。要求1,3相同;2,4相同
        // var res = str.match(/(\d)(\d)\1\2/g);
        // 要求:匹配連續四個數字。要求1,2相同;3,4相同
        var res = str.match(/(\d)\1(\d)\2/g);
        console.log(res);
    </script>

輸出結果:
在這裏插入圖片描述
禁止引用
(?:正則) 這個小括號中的內容不能夠被引用
在這裏插入圖片描述

4. 正則表達式匹配中文(utf-8編碼)

每個字符(中文、英文字母、數字、各種符號、拉丁文、韓文、日文等)都對應着一個Unicode編碼。
查看Unicode編碼,找到中文的部分,然後獲取中文的Unicode編碼的區間,就可以用正則匹配了。
前面我們用[a-z]表示小寫字母,[0-9]表示數字,這就是一個範圍表示,如果有一個數x能夠表示第一個中文,有一個數y能夠表示最後一箇中文,那麼[x-y]就可以表示所有的中文了。
中文的Unicode編碼從4E00開始,到9FA5結束。
[4E00-9FA5]這個區間就能夠表示中文。
JS語法:[\u4e00-\u9fa5]
完整的Unicode編碼表:http://blog.csdn.net/hherima/article/details/9045861

    <script>
        var str = '我是好人I’m a good man';
        var result = str.match(/[\u4E00-\u9FA5]{4}/g);
        console.log(result)
    </script>

輸出結果:
在這裏插入圖片描述

5. 環視(斷言/零寬斷言/正向預測/負向預測)

(?=n)匹配任何其後緊接指定字符串 n 的字符串。
有一個字符串是“abacad”,從裏面查找a,什麼樣的a呢?後面必須緊接b的a。

正則語法是: /a(?=b)/g

相反

(?!n)匹配任何其後沒有緊接指定字符串 n 的字符串。
有一個字符串是“abacad”,從裏面查找a,什麼樣的a呢?後面不能緊接b的a。
正則語法是: /a(?!b)/g

  <!-- 環視(斷言/零寬斷言/正向預測/負向預測) -->
  <script>
    var str = 'abacad';
    // 查詢後面是 b 的 a
    var res = str.match(/a(?=b)/g);
    console.log(res);    //=> ["a"]
  </script>
  <script>
    var str = 'abacad';
    // 查詢後面不是 b 的 a
    var res = str.match(/a(?!b)/g);
    console.log(res);    //=> ["a", "a"]
  </script>

  <!-- 小例子 -->
  <script>
    var str = 'php7 and HTML5';
    // 匹配後面跟着數字的字母字符串
    var res = str.match(/[A-Za-z]+(?=\d)/g);
    var res2 = str.match(/[A-Za-z]+(?!\d)/g);
    console.log(res,res2)   //=>["php", "HTML"], ["ph", "and", "HTM"]
  </script>

輸出結果:
在這裏插入圖片描述

(1)環視的過濾效果

(?!B)[A-Z]這種寫法,其實它是[A-Z]範圍裏,排除B的意思,前置的(?!B)只是對後面數據的一個限定,從而達到過濾匹配的效果。

<!-- 環視的過濾效果 -->
  <script>
    var str = 'ABCDEFGHIJKLMN';
    var res = str.match(/(?!B)[A-Z]/g);
    console.log(res);   //=> ["A", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N"]
  </script>

輸出結果:
在這裏插入圖片描述

(2)環視的限定效果

在過濾的基礎上,限定正則表達式。用法相同。
在這裏插入圖片描述
輸出結果:
在這裏插入圖片描述

6. 正則對象的屬性和方法

正則對象中的成員方法和屬性的正確調用方式:
和String對象類似:
一種是直接量語法(/[a-z]/.exec())
另一種方法是實例化正則對象,然後通過對象去調用成員方法(var reg = new RegExp(/[a-z]/); reg.exec()

類似字符串:

  • ‘hello’.substr(1);
  • var s = new String(‘hello’); s.substr(1);

(1)exec方法和lastIndex屬性

exec方法執行一個正則匹配,只匹配一次,匹配到結果就返回一個數組類型的結果,匹配不到就返回null。並將表示匹配的位置 置爲下一個匹配的位置。
lastIndex一個整數,標示開始下一次匹配的字符位置。沒有更多匹配重置lastIndex爲0.
依次調用exec匹配下一個的例子:
依次調用exec,會將匹配的位置不斷的後移,直至結尾。

  <script>
    var str="The rain in Spain stays mainly in the plain";
    var rex =/ain/g;

    var i = rex.lastIndex;
    var res = rex.exec(str);
    console.log(i,res);

    var i = rex.lastIndex;
    var res = rex.exec(str);
    console.log(i,res);

    var i = rex.lastIndex;
    var res = rex.exec(str);
    console.log(i,res);

    var i = rex.lastIndex;
    var res = rex.exec(str);
    console.log(i,res);
    
    var i = rex.lastIndex;
    var res = rex.exec(str);
    console.log(i,res);
  </script>

輸出結果:
在這裏插入圖片描述

(2)test 方法

test方法檢測目標字符串和正則表達式是否匹配,如果匹配返回true,不匹配返回false。

  <!-- test方法 -->
  <script>
    /* 直接量語法調用 */
    var str="The rain in Spain stays mainly in the plain";
    var rex =/ain/g;
    var res = rex.test(str);
    console.log(res);  //=> true
  </script>
  <script>
    /* 實例化對象進行調用 */
    var rex = new RegExp(/ain/,'g')
    var str="The rain in Spain stays mainly in the plain";
    var res = rex.test(str);
    console.log(res);  //=> true
  </script>

輸出結果:
在這裏插入圖片描述

7. 支持正則表達式的 String 對象的方法

(1)search()

在字符串中搜索符合正則表達式的結果。如果找到結果返回結果的位置,停止向後檢索,也就是說忽略全局標識符g;如果沒有匹配結果,返回-1。

  <script>
    var str = 'Hello world';
    var rex = /l/;
    var res = str.search(rex);
    console.log(res);  
  </script>

輸出結果:
在這裏插入圖片描述

(2)match()

在字符串中檢索匹配正則表達式的子串;如果匹配,返回包含匹配結果的一個數組;不匹配返回null。
不加全局g的情況:
獲取的結果只是第一個匹配的內容,匹配的內容中的第一個單元是匹配的結果,後面的單元是子表達式
非全局下:

  <script>
    var str = '1122 3434 5656 1234 1221 2002';
    var rex = /\d(\d)\1\d/;
    var res = str.match(rex);
    console.log(res);  
  </script>

輸出結果:
在這裏插入圖片描述
全局下:
獲取的結果是所有匹配的內容,但是不包含子表達式。

 <script>
    /* 全局 */
    var str = '1122 3434 5656 1234 1221 2002';
    var rex = /\d(\d)\1\d/g;
    var res = str.match(rex);
    console.log(res);  
  </script>

輸出結果:
在這裏插入圖片描述
注意: 不管全局還是非全局調用多次和調用一次的結果相同

(3)split()

將字符串分割成數組:
特點是可以用正則表達式來分割字符串。

<!-- split -->
  <script>
    var str = '[email protected]';
    // 用@來分割郵箱
    var rex = /@/g;
    var res = str.split(rex);
    console.log(res);  //=>  ["1131260584", "qq.com"]
  </script>

輸出結果:
在這裏插入圖片描述

(4)replace()

默認只替換一次,加g全部替換。加入全局的g:

   <!-- replace -->
  <script>
    var str = 'hello world';
    // var res = str.replace('l','L');//=>heLlo world
    // var res = str.replace(/l/,'L');//=>heLlo world
    var res = str.replace(/l/g,'L');//=>heLLo worLd
    console.log(res);
  </script>

替換的時候,使用"$1"表示第一個子表達式:
用$2表示第二個子表達式,以此類推。

/* 將abc替換成aabbcc */
<script>
    var str = 'abc';
    var res = str.replace(/([a-z])/g,'$1$1');
    console.log(res);
</script>

輸出結果:
在這裏插入圖片描述
替換abc爲a[a-b-c]c ghk g[g-h-k]k
在這裏插入圖片描述

  <script>
    var str = 'abc';
    var res = str.replace(/(b)/g,"[$` -$1- $']");
    console.log(res);
  </script>

輸出內容:
在這裏插入圖片描述
替換aaa bbb ccc爲Aaa Bbb Ccc,演示可以用函數來進行復雜的替換。
說明: replace具有遍歷的效果。

  <script>
    var str = 'aaa bbb ccc';
    var res = str.replace(/[a-z]+/g,function(x){
      return x.substr(0,1).toUpperCase()+x.substr(1);
    });
    console.log(res);
  </script>

輸出結果:
在這裏插入圖片描述

8. 案例

(1)匹配手機號格式是否正確

/* 驗證手機格式 */
/**
*要求:
*1,1開頭
*2,廠商代號
*3,11位數全數字
*/
/* 正則表達式 */

/^1(56|59|50|57|36|89|58)\d{8}$/g

(2)匹配郵箱格式是否正確

/* 驗證郵箱格式 */
/**
*要求:
*1,@ 前6-14位數字與字母的組合,允許有符號比如 . - 等合法符號至多2個,@前一位不能是符號
*2,@ 後直接跟.com,也可以163.com,也可以163.com.cn
*/
/* 正則表達式 */

/^[A-z0-9][\w\.\-]{2}[A-z0-9]{3-11}@[a-z0-9]+(\.[A-z]+)+/g

(3)解決結巴程序

<script>
    var str = '今今今今今今今今天晚晚晚晚晚晚晚上吃吃吃雞雞雞雞雞'    
    var r = /([\u4e00-\u9fa5])\1*/g;   //表示先捕獲中文,再引用,利用量詞*匹配相同中文
    var result  = str.replace(r,'$1');
    console.log(result);
</script>

結果:
在這裏插入圖片描述

(4)用戶名驗證

/* 用戶名的驗證 */

/* *
* 要求:
* 1,不能純字母
* 2,開頭不能是數字
* 3,長度範圍5-9
* 4,沒有符號
*/
/* 正則表達式 */

/(?!^[A-z]+$)^[A-z][A-z0-9]{4,8}$/g

9. PHP中的正則表達式

php中沒有修飾符。

(1)正則函數

1. preg_match()

相當於非全局匹配。
preg_match()返回匹配的次數,它的返回值是0或者是1。

  • 0表示不匹配。
  • 1表示匹配一次,因爲preg_match在匹配一次之後就停止向後檢索了。
<?php
$str = 'hello world';
$rex = '/[a-z]/';
/**
 * preg_match
 * 返回值是0或1
 * $str 要執行正在匹配的字符串
 * $rex 正則表達式
 * $out 匹配內容,以一個數組的形式輸出
 */
echo preg_match($rex,$str,$out);
echo '<pre>';  //預輸出
print_r($out);

輸出結果:
在這裏插入圖片描述
帶子表達式的例子

/* 帶有子表達式匹配的例子 */
$str = '1122 3455 6677 8989';
$rex = '/(\d)\1(\d)\2/';
echo preg_match($rex,$str,$out);
echo '<pre>';
print_r($out);

輸出結果:
在這裏插入圖片描述

2. preg_match_all()

相當於全局匹配。

<?php
$str = 'hello world';
$rex = '/[a-z]/';
echo preg_match_all($rex,$str,$out);
echo '<pre>';
print_r($out);

輸出結果:
在這裏插入圖片描述
帶子表達式的例子

/* 帶有子表達式匹配的例子 */
$str = '1122 3455 6677 8989';
$rex = '/(\d)\1(\d)\2/';
echo preg_match_all($rex,$str,$out);
echo '<pre>';
print_r($out);

輸出結果:
在這裏插入圖片描述

3. preg_replace()

執行正則替換,替換字符串:
注意: 在php中preg_replace默認全部替換

<?php
    $str = 'hello world';
    $r = '/l/';
    echo preg_replace($r,'L',$str);

輸出結果:
在這裏插入圖片描述
帶子表達式:

<?php
    $str = 'abcd123';
    $r = '/([a-z])/';
    echo preg_replace($r,'$1$1',$str);

輸出結果:
在這裏插入圖片描述
替換數組:

<?php
    $arr = array('javascript','php7','es6','html5');
    $res = preg_replace('/(\d)/','$1$1',$arr);
    echo '<pre>';
    print_r($res);

輸出結果:
在這裏插入圖片描述

4. php中匹配中文

<?php
$res=array();
$str="你好aaaaa啊";
preg_match_all('/[\x{4e00}-\x{9fa5}]+/u',$str,$res);
echo '<pre>';
print_r($res);
//輸出
//Array ( [0] => Array ( [0] => 你好 [1] => 啊 ) )

輸出結果:
在這裏插入圖片描述

5. PHP中使用正則注意點

  • PHP中的使用正則的使用除了//以外,外面還要加引號,這個引號要用單引號。
    在這裏插入圖片描述
  • 無論是JS中,還是PHP中,正則表達式的匹配模式默認都是貪婪模式。

6. 解決貪婪模式

貪婪模式:
在這裏插入圖片描述
上述代碼,查詢至少一個字母。但是在實際匹配的過程中,匹配到一個a之後,並沒有停止,而是繼續向後匹配,得到一個連續的字符串。這就是貪婪模式。
下面在正則表達式後面加入?,表示非貪婪模式:
在這裏插入圖片描述
默認是貪婪模式,必須使用非貪婪模式的例子:
在這裏插入圖片描述
PHP中,強制非貪婪模式:
加入大寫的修飾符U即可。
在這裏插入圖片描述

發佈了37 篇原創文章 · 獲贊 6 · 訪問量 2220
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章