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

    什么是正则?

    正则表达式(regular expression)是一种表达文本模式(即字符串结构)的方法,有点像字符串的模板,常常用来按照“给定模式”匹配文本。比如,正则表达式给出一个 Email 地址的模式,然后用它来确定一个字符串是否为 Email 地址。JavaScript 的正则表达式体系是参照 Perl 5 建立的。

    建立正则表达式

    使用内置RegExp构造函数

    var reg=new RegExp("martin");

    直接建立

    var reg=/martin/;

    以上两种建立正则的方式是等效的,,不过一般第二种方式用的更多一些。

    接受参数

    正则表达式除了接受一个字面量字符参数,还可以接受一个修饰符作为参数。

    var reg=/martin/g
    
    //var reg=new RegExp("martin","g");

    说完基本的正则概念和接受参数,接下来说一下正则的匹配规则,这一块也是面试和笔试考察的重点。

    匹配规则

    在说匹配规则之前我们先说一下正则中的字符分类。

    字面量字符和元字符

    字面量字符:只表示它字面的含义,就像上面代码中的martin,也就是实际用于匹配的字符。

    元字符:不代表字符本身字面的意思,而是有特殊含义的字符,也就是帮助字面量字符达到更好的匹配效果的辅助字符。

    其中元字符又分为很多类,具体类型如下:

    元字符

    点字符(.)

    匹配除回车( )、换行( ) 、行分隔符(u2028)和段分隔符(u2029)以外的所有字符

    位置字符号(^和$)

    • $ 表示字符串的结束位置
    • ^ 表示字符串的开始位置

    选择符(|)

    竖线符号(|)在正则表达式中表示“或关系”(OR)

    • 点字符(.
    var reg=/1.3/;  //表示匹配1和3之间包含任意一个字符的情况,除特殊符外,如:"1-3","1.3","123"等;
                    //但是一个点只能匹配一个字符,如:"1223"则无法匹配成功
    • 位置字符(^和$)
    var reg=/^13/;  //表示以"13"字符串开头的字符串
    reg.test("134") //true
    
    var reg=/13$/; //表示以"13"字符串结束的字符串
    reg.test("134") //false
    reg.test("4 31") //true
    
    var reg=/^13$/; //注意:表示从开始到结束位置只有"13"这个字符串
    reg.test("13") //true
    reg.test("1313") //false

    注意:  /^13$/ 这个正则表达式很容易让人理解成匹配以字符串"13"开始和结尾的字符串,如:"1313",但实际上它是表示从开始到结束位置只有"13"这个字符串。

    • 选择符(|)
    var reg=/11|22||33/; //表示匹配"11"或者"22"或者"33"
    reg.test("11") //true
    reg.test("22") //true

    注意:选择符会匹配包括它前后的多个字符,比如  /11|22/指的是匹配"11"或者"22",而不是指匹配1或者2,。如果想匹配1或者2,可以添加括号来实现,如:  

    var reg=/1(1|2)2/;
    reg.test("112")  //true
    reg.test("122")  //true

    转义字符

    如果要在正则表达式中使用具有特殊含义的字符,如:$,^等,也就是如果要匹配它们本身,那就需要用到转义字符了,也就是在他们前面加上""反斜杠,比如要匹配$,则写成$。

    正则表达式中,需要反斜杠转义的,一共有12个字符:^.[$()|*+?{\。需要特别注意的是,如果使用RegExp方法生成正则对象,转义需要使用两个斜杠,因为字符串内部会先转义一次。

    var reg=/1$/;   //表示匹配字符串"1$",而不是以1结尾的字符串
    reg.test("1")   //false
    reg.test("1$")  //true

    特殊字符

    正则表达式对一些不能打印的特殊字符,提供了表达方法。

    • cX 表示Ctrl-[X],其中的X是A-Z之中任一个英文字母,用来匹配控制字符。
    • [] 匹配退格键(U+0008),不要与混淆。
    • 匹配换行键。
    • 匹配回车键。
    • 匹配制表符 tab(U+0009)。
    • v 匹配垂直制表符(U+000B)。
    • f 匹配换页符(U+000C)。
    • 匹配null字符(U+0000)。
    • xhh 匹配一个以两位十六进制数(x00-xFF)表示的字符。
    • uhhhh 匹配一个以四位十六进制数(u0000-uFFFF)表示的 Unicode 字符。

    字符类

    字符类表示有一系列字符可供选择,只要匹配其中一个就可以。表示方法为将所有可供选择的字符都放在方括号内,比如[xyz]表示匹配x、y、z中的任意一个就可以。

    var reg=/[abc]/;  //表示匹配a,b,c中任一字符皆可
    reg.test("hello") //false
    reg.test("apple") //true

    说到这里同学们应该会想到之前说过的选择符吧,[xyz]就等效于(x|y|z),两者可相互转换。

    Q:那既然两种字符功能可以相互转换,为啥有了选择符还要字符类呢? 

    A:因为字符类除了能表示选择,还包括另外两种字符,脱字符和连字符,这两种字符又有新的功,可以将字符类理解成选择符的一种超集。 

    • 脱字符(^)

    表示可以匹配除字符类中字符以外的所有字符,因为这个符号和位置字符中的"^"开始位置字符是相同的,所以在使用时要注意区别,直接"^"放在正则表达式开头的是位置字符,放在"[]"中开头的"^"表示的是脱字符。

    var reg=/^123/;   //位置字符
    reg.test("1234"); //true
    
    var reg=/[^123]/; //脱字符
    reg.test("123");  //false
    reg.test("4")     //true
    • 连字符(-)

    表示匹配连续字符序列中的任意一个字符,如:[abcdef]可以写成[a-f],[012345678]可以写成[0-9]等,这大大提升了字符类书写的简便性。

    var reg=/0-9/; //表示匹配字符串"0-9"
    reg.test("0") //false
    reg.test("0-9")//true
    
    var reg=/[0-9]/;
    reg.test("0") //false

    ==注意:虽然连字符用起来十分简便,但是一定要避免过度使用连字符,因为连字符往往设定的是一个比较大的范围,如果不注意可能会匹配到意料之外的一些字符。比如:[A-z],表面上它是要匹配到A-Z和a-z这52个字符,但是实际上在ASCII编码中,在Z和a之间还有很多其他字符,所以可能机会出现意料之外的匹配效果。

    var reg=/[A-z]/;
    reg.test('[');    //true

    分析:因为"["字符在Z和a之间,所以也能被匹配到。

    预定义模式

    预定义模式是指某些常见模式的简写方式,可以理解成是内置的正则表达。

    • d 匹配0-9之间的任一数字,相当于[0-9]
    • D 匹配所有0-9以外的字符,相当于[^0-9]
    • w 匹配任意的字母、数字和下划线,相当于[A-Za-z0-9_]
    • W 除所有字母、数字和下划线以外的字符,相当于[^A-Za-z0-9_]
    • s 匹配空格(包括换行符、制表符、空格符等),相等于[ vf]
    • S 匹配非空格的字符,相当于[^ vf]
    •  匹配词的边界。
    • B 匹配非词边界,即在词的内部。

    重复类

    模式的精确匹配次数,使用大括号({})表示。{n}表示恰好重复n次,{n,}表示至少重复n次,{n,m}表示重复不少于n次,不多于m次,默认匹配的是单个字符,若想要重复字符串,可以使用括号。

    var reg=/12{2,5}3/; //默认表示匹配单个字符"2"的次数为2-5次
    reg.test("1223")    //true 
    reg.test("12123")   //false
    
    var reg=/(12){2,5}3/; //表示匹配字符串"12"的次数为2-5次
    reg.test("1223")    //false 
    reg.test("12123")   //true
     

    量词符

    量词符是内置用来设定某个模式出现的次数的,默认也是匹配单个字符的次数。

    • ? 问号表示某个模式出现0次或1次,等同于{0, 1}
    • * 星号表示某个模式出现0次或多次,等同于{0,}
    • + 加号表示某个模式出现1次或多次,等同于{1,}

    贪婪和非贪婪模式

    • 贪婪模式(默认):即最大可能匹配,匹配直到下一个字符不满足匹配规则为止,上面说的三个量词符,默认模式都为贪婪模式。
    var s = 'aaa';
    var reg=/a+/;
    s.match(reg);   //["aaa"]
    • 非贪婪模式:即最小可能匹配,匹配到一个满足匹配规则的字符就停止,将贪婪模式改为非贪婪模式只需要在量词符后面加一个问号。
    var s = 'aaa';
    var reg=/a+?/;
    s.match(reg);   //["a"]

    总结:

    • *?:表示某个模式出现0次或多次,匹配时采用非贪婪模式。
    • +?:表示某个模式出现1次或多次,匹配时采用非贪婪模式。

    修饰符

    修饰符(modifier)表示模式的附加规则,放在正则模式的最尾部,有g,i,m三种修饰符。

    修饰符可以单个使用,也可以多个一起使用。

    // 单个修饰符
    var reg = /test/i;
    
    // 多个修饰符
    var reg = /test/ig;
    • g修饰符

    默认情况下,第一次匹配成功后,正则对象就停止向下匹配了。g修饰符表示全局匹配(global),加上它以后,正则对象将匹配全部符合条件的结果,主要用于搜索和替换。

    var s = 'aaa';
    var reg=/a+?/;
    s.match(reg);   //["a"]
    
    var s = 'aaa';
    var reg=/a+?/g;
    s.match(reg);   //["a","a","a"]
    • i修饰符

    默认情况下,正则对象区分字母的大小写,加上i修饰符以后表示忽略大小写(ignorecase)

    var s = 'Aaa';
    var reg=/a/;
    s.match(reg);   //["a"]
    
    var s = 'Aaa';
    var reg=/a/i;
    s.match(reg);   //["A"]
    • m修饰符

    m修饰符表示多行模式(multiline),会修改^$的行为。默认情况下(即不加m修饰符时),^$匹配字符串的开始处和结尾处,加上m修饰符以后,^$还会匹配行首和行尾,即^$会识别换行符( )。

    var s = 'ab
     ab';
    var reg=/ab$/m;
    s.match(reg);   //["ab"]
    
    var s = 'ab
     ab';
    var reg=/ab$/gm;
    s.match(reg);   //["ab","ab"]会按行进行匹配,会识别
    换行符,这里的第一行以ab结尾,第二行也以ab结尾
  • 相关阅读:
    从1到n中找到任意num个数的和为sum的所有组合
    算法导论5.12
    使用c++技术实现下载网页
    算法导论5.13
    感慨
    算法导论2.37
    [转载]Yahoo!的分布式数据平台PNUTS简介及感悟
    Bigtable 论文笔记
    GFS 论文笔记
    MapReduce论文笔记
  • 原文地址:https://www.cnblogs.com/liutianzeng/p/11434602.html
Copyright © 2011-2022 走看看