• 【犀牛书笔记】JavaScript正则表达式的模式匹配


    正则表达式,是一个描述字符模式的对象。

    JavaScript用RegExp类表示正则表达式

    String和RegExp都定义了相关方法

    原创文章,转载请注明:http://www.cnblogs.com/phpgcs/

    通过正则表达式进行强大的“模式匹配”和“文本检索与替换”功能

    • 内容1:正则表达式的定义
      • 直接量字符
      • 字符类
      • 重复
      • 选择,分组,引用
      • 指定匹配位置
      • 修饰符
    • 内容2:用于模式匹配的String方法
      • search()
      • replace()
      • match()
      • split()
    • 内容3:regexp对象
      • exec()
      • test()

    构建正则对象的方法:

    1. var pattern = /s$/;
    2. var pattern = new RegExp("s$");

    10.1 正则表达式的定义

    10.1.1 直接量字符

    所有的字母/数字 都是按照字面含义进行匹配
    非字母的字符匹配需要通过 前缀进行转义

    • o NULL(u0000)
    • 制表符(u0009)
    • 换行符(u000A)
    • v 垂直制表符(u000B)
    • f 换页符(u000C)
    • 回车符(u000D)
    • xnn 由16进制nn指定的拉丁字符
    • uxxxx 由16进制xxxx指定的Unicode字符
    • cX 控制字符^X

    特殊含义的标点符号:
    ^ $ . + ? ! : | / ( ) ] { }

    某些符号只有在正则的某些上下文中才有某种特殊含义,在其他地方则当成直接量处理
    通行的规则:用前缀来匹配特殊字符的直接量
    对于数字和字母,尽量不要用 前缀,那是有特殊意义的。

    10.1.2字符类

    将直接量字符 单独放进 [] 就组成了字符类(character class)
    /[abc]/匹配 a b c的任意一个
    /[^abc]/定义来一个“否定字符类”,匹配除了a b c的字符
    常用:/[a-z]/,/[a-zA-Z0-9]/

    • [...]
    • [^...]
    • . 任意字符,除了换行符/其他Unicode行终止符号
    • w 任何ASCII组成的单词,等价[a-zA-Z0-9]
    • W 任何非。。。。,等价[^a-zA-Z0-9]
    • s 任意Unicode空白符
    • S 任意非Unicode空白符,区分跟w的区别
    • d 任意ASCII数字,等价[0-9]
    • D [^0-9]
    • [] 退格直接量

    10.1.3重复

    • {n,m}
    • {n,}
    • {n}
    • ?

    这些重复默认都是“贪婪的”,允许后续的正则表达式继续匹配。

    举例:

    /a+/匹配"aaa"结果"aaa"

    /a+b/匹配"aaab"结果“aaab"

    非贪婪模式,在重复字符后面加上?

    举例:

    /a+?/匹配"aaa"结果"a",第一个"a"

    /a+?b/匹配"aaab"结果“aaab",跟贪婪一样

    它是应该匹配尽可能少的"a"和一个"b",而匹配总是会寻找字符串中”第一个可能匹配的位置“

    思考:如果就要匹配"ab"呢?

    10.1.4 选择、分组和引用

    选择有个特点,就是一旦匹配到左边的结果,就会忽略右边的

    /a|ab/匹配"ab"结果"a"

    这里要说说圆括号()的多个作用:

    1. 把单独的项组合成子表达式,(...)以便可以用 | * + ? 来对这个子表达式进行处理
      /java(script)?/可以匹配"java"也可以匹配"javascript"
    2. 在完整的模式中定义子模式,以便后续的处理
    3. 允许在同一个正则表达式的后部引用前面的子表达式

    通过1,2...实现

    常用的例子比如匹配html标记 <(S?)[^>]>.?</1>|<.? />

    再比如/(['"])[^'"]*1/匹配"display:none;"这样子左右侧的引号要相匹配

    正则不允许用"括起的内容中有',反之亦然
    不允许在“字符类”中使用1这种引用
    (?:[Ss]cript)仅仅用于分组,而不生成引用

    • | 选择
    • (...) 组合
    • (?:...) 只组合,但不记忆
    • 引用记忆

    10.1.5指定匹配位置(锚)

    •  匹配单词边界,即位于w W之间的边界,注意[]匹配的则是退格符
    • ^
    • $
    • B
    • (?=p) 零宽正向先行断言,要求接下来的字符都与p匹配,但不包括匹配p的那些字符
    • (?!p) 零宽负向先行断言

    /^JavaScript$/匹配"JavaScript"
    /sJavas/匹配" Java ",无法匹配到开头/结尾的"Java",也有多余的空格
    /Java/就可以补充以上2点
    /Bscript/匹配"postscript",而不匹配"script","scripting"

    任意正则表达式都可以作为一个锚点条件

    先行断言:(?=...)

    /[Jj]ava([Ss]cript)?(?=:)/ 只在后面有冒号时才匹配

    匹配"JavaScript: The Definitive Guide"中的Javascript

    不匹配"Javascript in a Nutshell"中的Javascript

    负向先行断言:(?!...), 用以指定接下来的字符不必匹配

    /Java(?!Script)([A-Z]w*)/

    匹配"Java"后跟随一个大写字母和任意多个ASCII单词,但是后面不能跟随Script

    匹配成功:"JavaBeans"

    匹配失败:"Javanese","JavaScript","JavaScripter"

    10.1.6修饰符

    • i 不区分大小写
    • g 全局匹配,找到所有的匹配
    • m 多行匹配模式,^匹配一行的开头和字符串的开头
    • $匹配行的结束和字符串的结束

    10.2 用于模式匹配的String方法

    • search()
    • replace()
    "JavaScript".search(/script/i);
    4
    "JavaScript".search(/script/);
    -1
    不支持全局搜索,会忽略/g
    "abababab".replace(/a/gi,"A");
    "AbAbAbAb"
    "abababab".replace(/a/gi,"M");
    "MbMbMbMb"
    "1 plus 2 equals 3".match(/d+/g);
    ["1", "2", "3"]
    "1 plus 2 equals 3".match(/d+/);
    ["1"]
    var text="http://www.cnblogs.com/phpgcs";
    var url=/(w+)://([w.]+)/(S*)/;
    text.match(url);
    ["http://www.cnblogs.com/phpgcs", "http", "www.cnblogs.com", "phpgcs"]
    //给match方法传入一个非全局的正则表达式,实际上跟exec()方法是一样的
    "123,456,789".split(",")
    ["123", "456", "789"]
    "123 , 456, 789".split(/s*,s*/);
    ["123", "456", "789"]
    

    10.3 RegExp对象

    var zipcode = new RegExp("d{5}", "g");

    这个构建函数非常有用,尤其是需要动态创建正则表达式的时候,比如用户输入。

    (通过eval()也可以实现在运行时动态创建这个正则,但是不推荐)

    另外,注意这个例子中的\,而不是,无论是“字符串直接量”还是“正则表达式”,都要使用""字符作为”转义字符前缀“

    除了构建正则之外,RE对象还支持3个方法和一些属性

    5个属性:

    var zipcode=new RegExp("\d{5}", "g");
    undefined
    zipcode
    /d{5}/g
    zipcode.source
    "d{5}"
    zipcode.global
    true
    zipcode.ignoreCase
    false
    zipcode.multiline
    false
    zipcode.lastIndex
    0
    

    2个方法:
    exec(),test()

    var pattern = /Java/g;
    var text = "JavaScript is more fun than Java!";
    var result;
    while((result = pattern.exec(text))!=null){ console.log("Matched '"+result[0]+"'"+" at position "+result.index+";next search begins at "+pattern.lastIndex);}
    Matched 'Java' at position 0;next search begins at 4
    Matched 'Java' at position 28;next search begins at 32
    var pattern = /Java/g;
    "JavaScript".test(pattern);
    pattern.test("JavaScript");
    true
    

    对比下这4+2=6种方法:

    String:search(),replace(),match(),split()

    RegExp:exec(),test()

    和 match() 不同,无论是否有 g,exec()都会返回一样的数组

    当 exec() 含 g,情况较复杂

    将会把当前pattern.lastIndex设置为紧邻匹配子串的字符位置(如上例子)

    当同一个pattern再一次调用exec(),将从lastIndex开始检索

    如果没有发现匹配结果,pattern.lastIndex重置0

    var pattern = /Java/g;
    var text = "JavaScript is more fun than Java Java Java!";
    text.match(pattern);
    ["Java", "Java", "Java", "Java"]
    pattern.exec(text);
    ["Java"]
    pattern.lastIndex
    4
    pattern.exec(text);
    ["Java"]
    pattern.lastIndex
    32
    pattern.exec(text);
    ["Java"]
    pattern.lastIndex
    37
    pattern.exec(text);
    ["Java"]
    pattern.lastIndex
    42
    pattern.exec(text);
    null
    pattern.lastIndex
    0
    pattern.exec(text);
    ["Java"]
    pattern.lastIndex
    4
    

    如果让一个带g的pattern对“多个”字符串执行exec()或者test(),

    要么需要在每个string中找出所有的匹配,以便将lastIndex自动重置0

    要么需要显式将lastIndex手动设置0(最后一次检索失败时)

    当然,如果RegExp不带有g修饰,则不必担心这个问题。

    在ECMAScript5中,正则的每次计算都会创建一个新的RegExp对象,各自有各自的lastIndex属性,将大大减少“残留”lastIndex对程序造成的意外影响。

    String的方法search(),replace(),match()并不会用到 lastIndex属性,只是简单的设置为0

  • 相关阅读:
    Coding4Fun.Phone.Controls的使用
    发布windows phone应用经历实谈
    我的第一款windows phone软件
    华农js抢课神器
    zookeeper 实战案例分享:cruator客户端编程
    zookeeper学习与实战(二)集群部署
    zookeeper学习与实战(一)环境部署
    Flask框架的学习与实战(三):登陆管理
    Flask框架的学习与实战(二):实战小项目
    Flask框架的学习与实战(一):开发环境搭建
  • 原文地址:https://www.cnblogs.com/phpgcs/p/javascript_definitive_guide_note_regularExpression.html
Copyright © 2020-2023  润新知