前端点滴(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 = '1131260584@qq.com';
    // 用@来分割邮箱
    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即可。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值