zoukankan      html  css  js  c++  java
  • 正则表达式

    正则表达式是一种用来匹配字符串的强有力的武器。它的设计思想是用一种描述性的语言来给字符串定义一个规则,凡是符合规则的字符串,我们就认为它“匹配”了,否则,该字符串就是不合法的。因此我们可以通过设计正则表达式很简单的实现对一些字符串格式的判定,如是否是合法的邮箱地址写法等。

    正则表达式的规则

    因为正则表达式也是用字符串表示的,所以,我们要首先了解如何用字符来描述字符。

    在正则表达式中,如果直接给出字符,就是精确匹配。用d可以匹配一个数字,w可以匹配一个字母或数字,所以:

    • '00d'可以匹配'007',但无法匹配'00A'

    • 'ddd'可以匹配'010'

    • 'ww'可以匹配'js'

    .可以匹配任意字符,所以:

    • 'js.'可以匹配'jsp''jss''js!'等等。

    要匹配变长的字符,在正则表达式中,用*表示任意个字符(包括0个),用+表示至少一个字符,用?表示0个或1个字符,用{n}表示n个字符,用{n,m}表示n-m个字符,s可以匹配一个空格(也包括Tab等空白符).

    举个例子:

    d{3}s+d{3,8}

    首先,d{3} 表示 匹配3个数字,比如 ‘110’;

    接着,s+ 表示至少有一个空格,比如‘  ’或‘ ’

    最后,d{3,8} 表示3-8个数字,比如‘11111’

    正常的字符我们可以采用上述的表达方式,但是如果是类似‘-’等特殊字符,我们在正则表达式中需要使用‘’转义字符进行转义,如‘-’。

    如果我们要做更精确地匹配,可以用[]表示范围,比如:

    •  [0-9a-zA-Z\_] 可以匹配一个数字、字母或者下划线;

    •  [0-9a-zA-Z\_]+ 可以匹配至少由一个数字、字母或者下划线组成的字符串,比如'a100''0_Z''js2015'等等;

    •  [a-zA-Z\_$][0-9a-zA-Z\_$]* 可以匹配由字母或下划线、$开头,后接任意个由一个数字、字母或者下划线、$组成的字符串,也就是JavaScript允许的变量名;

    •  [a-zA-Z\_$][0-9a-zA-Z\_$]{0, 19} 更精确地限制了变量的长度是1-20个字符(前面1个字符+后面最多19个字符)。

    A|B可以匹配A或B,所以(J|j)ava(S|s)cript可以匹配'JavaScript''Javascript''javaScript'或者'javascript'

    还有 一些

    ^表示行的开头,^d表示必须以数字开头。

    $表示行的结束,d$表示必须以数字结束。

    比如'js'可以匹配到‘jsp’,但是'^js$'则只能匹配'js'。

    以上是正则表达式的使用规则,下面说一下在JavaScript中如何使用正则表达式。

    正则表达式的使用

    JavaScript有两种方式创建一个正则表达式:

    第一种方式是直接通过 /正则表达式/ 写出来,第二种方式是通过 new RegExp('正则表达式') 创建一个RegExp对象。

    两种方式的效果是相同的,举个例子:

    var reg1 = '/110d+-/';
    var reg2 = new RegExp('110\d+\-');

    注意,如果使用第二种写法,因为字符串的转义问题,字符串的两个\实际上是一个

    如何判断一个字符串是否和正则表达式匹配?

    RegExp对象的test()方法可以测试给定的字符串是否符合条件。

    var reg1 = '/110d+-/';
    reg1.test('11011-');//true
    reg1.test('1101');//false

    正则表达式除了上述判断字符串是否匹配的作用外,还有其他更强有力的作用。

    切分字符串

    在JavaScript中字符串的分割可以利用split函数来完成,平常我们采用这种方式来分割:

    'a b   ,c'.split(' '); // ['a', 'b', '', '', ',' , 'c']

    显然这样达不到我们想要只提取出abc字符的要求,需要再对处理结果再处理才可以,但如果使用正则表达式我们可以一步获得想要的结果。

    'a b    , c'.split(/[s\,]+/);//['a','b','c']

    分组

    正则表达式除了能简单地判断是否匹配之外,还有提取子串的强大功能。用()表示的就是要提取的分组(Group)。

    而如果正则表达式定义了分组,那我们可以用exec()将分组内容提取出来。

    exec()方法在匹配成功后,会返回一个Array,第一个元素是正则表达式匹配到的整个字符串,后面的字符串表示匹配成功的子串。

    exec()方法在匹配失败时返回null

    举个例子:

    var re = /^(d{3})-(d{3,8})$/;
    re.exec('010-12345'); // ['010-12345', '010', '12345']
    re.exec('010 12345'); // null

    在这个例子中,我们定义了两个分组分别是 d{3} 表示3个数字和 d{3,8} 表示3-8个数字,若匹配,则结果会返回字符串本身和提取的分组。

    贪婪匹配

    正则表达式默认采取的是贪婪匹配原则,即匹配尽可能多的字符,比如:

    var reg = /(d+)(0*)/;
    reg.exec('11000');//['11000','11000',''];

    在这个例子中,第一个分组由于是贪婪匹配,因此将所有的数字都匹配到了这个分组中,而第二个分组自然就变成了空字符串。

    如果想要让第一个分组尽可能少的匹配,我们只需在+后面加个?即可让第一个分组不采用贪婪匹配:

    var reg = /(d+?)(0*)/;
    reg.exec('11000');//['11000','11','000'];

    全局匹配

    JavaScript中 g 特殊标志代表全局匹配,全局匹配可以多次执行exec()方法来搜索一个匹配的字符串。当我们指定g标志后,每次运行exec(),正则表达式本身会更新lastIndex属性,表示上次匹配到的最后索引:

    var s = 'JavaScript, VBScript, JScript and ECMAScript';
    var re=/[a-zA-Z]+Script/g;
    
    // 使用全局匹配:
    re.exec(s); // ['JavaScript']
    re.lastIndex; // 10
    
    re.exec(s); // ['VBScript']
    re.lastIndex; // 20
    
    re.exec(s); // ['JScript']
    re.lastIndex; // 29
    
    re.exec(s); // ['ECMAScript']
    re.lastIndex; // 44
    
    re.exec(s); // null,直到结束仍没有匹配到

    全局匹配类似搜索,因此不能使用/^...$/,那样只会最多匹配一次。

    正则表达式还可以指定i标志,表示忽略大小写,m标志,表示执行多行匹配。

  • 相关阅读:
    P1522 牛的旅行
    P1908 逆序对
    P1107 雷涛的小猫
    欧拉函数
    P2679 子串
    P1063 能量项链
    P1052 过河
    P1020 导弹拦截
    P1330 阳光封锁大学
    P1198 最大数
  • 原文地址:https://www.cnblogs.com/pfr-blog/p/6841397.html
Copyright © 2011-2022 走看看