zoukankan      html  css  js  c++  java
  • 《精通正则表达式》笔记 --- 选择引号内的文字

    这个例子出自《精通正则表达式》,做一下笔记帮助理解和记忆。

    第一版

    最简单的case就是考虑包含一对引号,那么写出来的表达式应该是这样的:

    ".*"

    但是这个未免太简单了吧,会有啥问题呢?假如输入的字符串长这样结果就会出问题拉。see...

    Input String: "Hello" and "World" Regex: ".*" Match: "Hello" and "World"

    为什么会全部匹配到呢?这是因为 * 是一个greedy(匹配优先)的量词,我觉得英文的意思更容易帮助我们理解。这意味着它会首先会'贪婪'得把所有的字符匹配完,匹配到最后一个字符发现没有字符可以匹配了,于是开始匹配下一个引号,它会首先回朔到最后一个引号前,然后开始匹配引号匹配引号,发现可以匹配,然后就完成了。这就是为啥整个字符串都被匹配了。

    第二版

    既然是因为greedy的量词导致的这个问题,那我们将其给成lazy(忽略优先)的量词 ----- *? 。当一个量词是忽略优先的话,那在匹配的时候,引擎会选择忽略这个忽略优先量词修饰的字符去匹配下一个字符,如果匹配则继续,如果不匹配则返回来匹配这个忽略优先量词修饰的字符。

    看一下这个例子,将表达式稍作修改,匹配结果就变鸟。

    Input String: "Hello" and "World" Regex: ".*?" Match-1: "Hello" Match-2: "World"

    好了,似乎这个版本已经圆满完成我们的任务啦。

    第三版

    那我们将需求继续变化一下,在程序的世界里有一种东西叫做转移字符,比如有个字符串长这样子"Hello, World!"+"。 直接上最终正则表达式。

    Input String: "Hello, World!"+" Regex: "(\.|[^\"])*" Match-1: No Match

    正则表达式中关键的是这个(\.|[^\"]),这个括号在正则表达式里是起到一个多选结构的作用,表示匹配括号内任意一个子表达式即匹配。这个括号里面由两部分,第一部分是\.,第二部分是[^\"]

    \.

    \.能够匹配任何的转义字符,严格来说是匹配任意以及其后面的字符,即使它们不是真正的转义字符。

    [^"]

    这个输入字符串最后一个引号是转移的引号,所以这个正则表达式没有匹配到任何的结果。这个结果是对的,这个功劳就要归结到这个[^\"],它的意思是匹配非"的任意字符。当引擎匹配到字符串最后发现"还未匹配,于是进行回溯,回溯到▴那个位置"Hello, World!"+ ▴ "。引擎会尝试去匹配[^\"],发现匹配失败,于是失败!

    假如我们将[^\"]换成[^"],那么在刚才那个位置的时候,[^"]就会匹配字符,然后之后的"会被外层的引号匹配,于是它的结果就是被匹配了。这显然是很奇怪的,当然如果你想要这么匹配也可以。

    其他版本

    还有一种方式是利用正则表达式里面的固化分组(Atomic grouping)或者占有优先量词(Possessive)。固化分组:"(?>(\.|[^"])*),占有优先量词:"(\.|[^"])*+"。在固化分组或者占有优先量词的匹配过程中,在固化分组内或者占有优先量词修饰的组内,如果一个字符已经被匹配那么之前的状态将会被舍弃,就防止它进行回溯。

    在这个例子中,"Hello, World!"+",当匹配到这个位置的时候("Hello, World!"+" ▴)发现没有办法继续匹配下去了,引擎会选择直接匹配失败,而不是回溯到之前的备用状态进行新的匹配。

    关键的概念

    例子虽然简单,但是出现了正则表达式中很多关键的概念,预知详情,请阅读《精通正则表达式》

    • 匹配优先量词(Greedy quantifier)
    • 忽略优先量词(Lazy quantifier)
    • 占有优先量词(Possessive quantifier)
    • 固化分组(Atomic grouping)
    • 字符组(Character Classes)
    • 多选结构(Alternation)

    本文纯属个人读书笔记,如有错误概不负责哟~~~

  • 相关阅读:
    pre 强制换行
    code标签和pre标签的定义
    angularJS绑定数据中对标签转义的处理二 与pre标签的使用
    angularJS绑定数据中对标签转义的处理
    html特殊字符
    js switch的使用 ng-switch的使用方法
    JS转换HTML转义符,防止javascript注入攻击,亲测可用
    MVC,MVP 和 MVVM 的图示 转自阮一峰先生网络日志
    AngularJs ngReadonly、ngSelected、ngDisabled
    你应该知道的jQuery技巧
  • 原文地址:https://www.cnblogs.com/imjustice/p/regex_select_text_in_quota.html
Copyright © 2011-2022 走看看