`
ygsilence
  • 浏览: 332837 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

正则表达式中后向引用、零宽断言、负向零宽断言的解释用法

    博客分类:
  • JS
阅读更多
正则表达式中后向引用、零宽断言、负向零宽断言的解释用法:
下面分别做详细的解释:
(1)后向引用
在匹配模式中使用小括号指定一个子表达式后,匹配这个子表达式的文本(也就是此分组捕获的内容)可以在表达式或其它程序中作进一步的处理。默认情况下,每个分组会自动拥有一个组号,规则是:从左向右,以分组的左括号为标志,第一个出现的分组的组号为1,第二个为2,以此类推,分组0对应整个正则表达式
实际上组号分配过程是要从左向右扫描两遍的:第一遍只给未命名组分配,第二遍只给命名组分配--因此所有命名组的组号都大于未命名的组号
你可以使用(?:exp)这样的语法来剥夺一个分组对组号分配的参与权.
后向引用用于重复搜索前面某个分组匹配的文本。例如,\1代表分组1匹配的文本。难以理解?
请看示例:
\b(\w+)\b\s+\1\b可以用来匹配重复的单词,像go go, 或者kitty kitty。这个表达式首先是一个单词,也就是单词开始处和结束处之间的多于一个的字母或数字(\b(\w+)\b),这个单词会被捕获到编号为1的分组中,然后是1个或几个空白符(\s+),最后是分组1中捕获的内容(也就是前面匹配的那个单词)(\1)。
你也可以自己指定子表达式的组名。要指定一个子表达式的组名,请使用这样的语法:(?<Word>\w+)(或者把尖括号换成'也行:(?'Word'\w+)),这样就把\w+的组名指定为Word了。要反向引用这个分组捕获的内容,你可以使用\k<Word>,所以上一个例子也可以写成这样:\b(?<Word>\w+)\b\s+\k<Word>\b。
使用小括号的时候,还有很多特定用途的语法。下面列出了最常用的一些:
表4.常用分组语法 分类 代码/语法 说明
捕获 (exp) 匹配exp,并捕获文本到自动命名的组里
(?<name>exp) 匹配exp,并捕获文本到名称为name的组里,也可以写成(?'name'exp)
(?:exp) 匹配exp,不捕获匹配的文本,也不给此分组分配组号
零宽断言 (?=exp) 匹配exp前面的位置
(?<=exp) 匹配exp后面的位置
(?!exp) 匹配后面跟的不是exp的位置
(?<!exp) 匹配前面不是exp的位置
注释 (?#comment) 这种类型的分组不对正则表达式的处理产生任何影响,用于提供注释让人阅读
我们已经讨论了前两种语法。第三个(?:exp)不会改变正则表达式的处理方式,只是这样的组匹配的内容不会像前两种那样被捕获到某个组里面,也不会拥有组号。“我为什么会想要这样做?”——好问题,你觉得为什么呢?

(2)零宽断言
这个概念比较的难记, 知道有这么个概念就行了.无关紧要.
接下来的四个用于查找在某些内容(但并不包括这些内容)之前或之后的东西,也就是说它们像\b,^,$那样用于指定一个位置,这个位置应该满足一定的条件(即断言),因此它们也被称为零宽断言。最好还是拿例子来说明吧:
断言用来声明一个应该为真的事实。正则表达式中只有当断言为真时才会继续进行匹配。
(?=exp)也叫零宽度正预测先行断言,它断言自身出现的位置的后面能匹配表达式exp。比如\b\w+(?=ing\b),匹配以ing结尾的单词的前面部分(除了ing以外的部分),如查找I'm singing while you're dancing.时,它会匹配sing和danc。
(?<=exp)也叫零宽度正回顾后发断言,它断言自身出现的位置的前面能匹配表达式exp。比如(?<=\bre)\w+\b会匹配以re开头的单词的后半部分(除了re以外的部分),例如在查找reading a book时,它匹配ading。
假如你想要给一个很长的数字中每三位间加一个逗号(当然是从右边加起了),你可以这样查找需要在前面和里面添加逗号的部分:((?<=\d)\d{3})+\b,用它对1234567890进行查找时结果是234567890。
下面这个例子同时使用了这两种断言:(?<=\s)\d+(?=\s)匹配以空白符间隔的数字(再次强调,不包括这些空白符)。

(3)负向零宽断言
前面我们提到过怎么查找不是某个字符或不在某个字符类里的字符的方法(反义)。但是如果我们只是想要确保某个字符没有出现,但并不想去匹配它时怎么办?例如,如果我们想查找这样的单词--它里面出现了字母q,但是q后面跟的不是字母u,我们可以尝试这样:
\b\w*q[^u]\w*\b匹配包含后面不是字母u的字母q的单词。但是如果多做测试(或者你思维足够敏锐,直接就观察出来了),你会发现,如果q出现在单词的结尾的话,像Iraq,Benq,这个表达式就会出错。这是因为[^u]总要匹配一个字符,所以如果q是单词的最后一个字符的话,后面的[^u]将会匹配q后面的单词分隔符(可能是空格,或者是句号或其它的什么),后面的\w*\b将会匹配下一个单词,于是\b\w*q[^u]\w*\b就能匹配整个Iraq fighting。负向零宽断言能解决这样的问题,因为它只匹配一个位置,并不消费任何字符。现在,我们可以这样来解决这个问题:\b\w*q(?!u)\w*\b。
零宽度负预测先行断言(?!exp),断言此位置的后面不能匹配表达式exp。例如:\d{3}(?!\d)匹配三位数字,而且这三位数字的后面不能是数字;\b((?!abc)\w)+\b匹配不包含连续字符串abc的单词。
同理,我们可以用(?<!exp),零宽度负回顾后发断言来断言此位置的前面不能匹配表达式exp:(?<![a-z])\d{7}匹配前面不是小写字母的七位数字。
请详细分析表达式(?<=<(\w+)>).*(?=<\/\1>),这个表达式最能表现零宽断言的真正用途。
一个更复杂的例子:(?<=<(\w+)>).*(?=<\/\1>)匹配不包含属性的简单HTML标签内里的内容。(<?(\w+)>)指定了这样的前缀:被尖括号括起来的单词(比如可能是<b>),然后是.*(任意的字符串),最后是一个后缀(?=<\/\1>)。注意后缀里的\/,它用到了前面提过的字符转义;\1则是一个反向引用,引用的正是捕获的第一组,前面的(\w+)匹配的内容,这样如果前缀实际上是<b>的话,后缀就是</b>了。整个表达式匹配的是<b>和</b>之间的内容(再次提醒,不包括前缀和后缀本身)。
分享到:
评论
1 楼 jateide 2013-12-27  
网上随便转载的东西,自己都没有经过使用,好意思发出来,而且还不标明转载和出处。

相关推荐

    精通正则表达式~~~

    精通正则表达式第三版 搜集于网络 前言..........I 第1章:正则表达式入门.... 1 解决实际问题... 2 作为编程语言的正则表达式... 4 以文件名做类比... 4 以语言做类比... 5 正则表达式的知识框架... 6 对于...

    正则表达式30分钟入门教程

    后向引用 使用小括号指定一个子表达式后,匹配这个子表达式的文本(也就是此分组捕获的内容)可以在表达式或其它程序中作进一步的处理。默认情况下,每个分组会自动拥有一个组号,规则是:从左向右,以分组的左括号为...

    Python正则表达式分组概念与用法详解

    主要介绍了Python正则表达式分组概念与用法,结合具体实例形式较为详细的分析了Python正则表达式中分组、引用、断言等概念与相关使用技巧,需要的朋友可以参考下

    qunit-regexp:用于断言正则表达式测试的 QUnit 插件。 使用它的好处是显示字符串和正则表达式值的失败输出

    qunit-正则表达式 用于断言正则表达式测试的 QUnit 插件。 使用它的优点是显示字符串和正则表达式值的失败输出。安装这个模块需要原始的 QUnit(在 npm 上作为qunitjs )才能运行。 npm install --save-dev qunitjs ...

    正则表达式环视概念与用法分析

    本文实例讲述了正则表达式环视概念与用法。分享给大家供大家参考,具体如下: 1.环视又叫预搜索和零宽断言 2.环视又划分为  (?=exp)肯定顺序环视  (?&lt;=exp)肯定逆序环视  (?!exp)否定顺序环视  (?&lt;exp)...

    正则表达式语句中的注释方法分享

    要包含注释的话,最好是启用“忽略模式里的空白符”选项,这样在编写表达式时能任意的添加空格,Tab,换行,而实际使用时这些都将被忽略。启用这个选项后,在#后面到这一行结束的所有文本都将被当成注释忽略掉。例如...

    jmeter实例(json断言+参数化)

    jmeter实例(json断言+参数化),检查点详细介绍、正则表达式使用方法、JSON断言、CSV参数化

    regex-assert-symfony:在Symfony实体中与Assert一起使用的通用正则表达式

    正则表达式-断言-Symfony 在Symfony的实体中与Assert一起使用的Commun Regex名姓城市与国际名称兼容图案/^[a-zA-ZàáâäãåąčćęèéêëėįìíîïłńòóôöõøùÞúûüųūæÿýżźñçčšžÀÁ...

    node-re2:RE2的node.js绑定

    RE2的正则表达式语言几乎是RegExp提供的功能的超集(请参见 ),但是它缺少两个功能:向后引用和预言断言。 请参阅下面的更多细节。 RE2对象模仿标准RegExp使其在大多数情况下可作为RegExp替代产品。 RE2被扩展为...

    Golang Sample.zip

    实用Golang语言写的例子,包含...8_2正则表达式.go 8_3正则表达式.go 9_1通过结构体生成json.go 9_2通过map生成json.go 9_3json解析到结构体.go 9_4json解释到map.go 11 并发编程 12_1 Socket编程 12_2 Http编程

    regress:使用EcmaScript语法在Rust中使用REGex

    回归是在Rust中实现的回溯正则表达式引擎,其目标是JavaScript正则表达式语法。有关更多信息,请参见。 它是快速的,支持Unicode的,几乎没有依赖关系,并且具有很大的测试套件。它提供的保证少于regex但是它启用了...

    peg:Peg,解析表达式语法,是Packrat解析器生成器的实现

    Packrat解析器是一种“下降递归解析器”,能够回溯和对正则表达式引擎造成问题的否定超前断言。 也可以看看 正在安装 go get -u github.com/pointlander/peg 建筑 使用预先生成的文件 go install 自己生成文件 ...

    assertable:断言库,可以在方法参数可能导致更深层的问题之前测试方法参数的类型是否存在

    注意-这只是使用Javascript进行开发的一种方法,一些开发人员倾向于将责任转移给调用者,而不是在每种方法中强制执行类型。 与任何事情一样,这都取决于个人喜好。特征声明或测试参数或变量的类型,包括: 数组布尔...

    Python 核心编程 第二版

    第2部分则提供了各种高级主题来展示可以使用Python做些什么,包括正则表达式、网络编程、网络客户端编程、多线程编程、图形用户界面编程、 Web编程、数据库编程、扩展Python 和一些其他材料。  本书适合Python初学...

    Jmeter+ant+jenkins接口层性能与自动化测试

    2、参数化、badboy测试脚本开发以及录制方法,正则表达式之Regextester工具使用、JMETER 组件作 用域等知识点讲解。 3、ant 介绍以及作用、ant 下载及安装、ant build.xml 详解。 4、Jenkins 构建自动化平台、...

    JMETER 性能测试入门到项目实战视频课程

    2、参数化、badboy测试脚本开发以及录制方法,正则表达式之Regextester工具使用、JMETER 组件作 用域等知识点讲解。 3、本课程注重实践每一个知识点都有相对应的实例,本书覆盖的实例多达上百个,提高学员的动手能 ...

    match-json:一个用于测试JSON APIJavaScript库

    该库使用它来支持使用函数和正则表达式来声明JSON API。 您应该携带自己喜欢的测试库。 安装 npm install match-json 用法 匹配JSON基元。 // Numbers match ( 3.1415 , 3.1415 ) ; // =&gt; true //Strings match ( ...

    PythonTutorial:该存储库包含我的Python项目的代码段

    美化剂,Pylint,Pychecker 多态性引发异常正则表达式设置,元组,列表,数组,字典单元测试网址库使用Statement,Contex Manager,Contextlib XML格式发电机产量代码可视化器 设计模式 行为的创造力的结构性

    blue-tape:具有承诺支持的子堆栈的磁带测试运行器

    该项目不再维护。... 如果提供了可选类或regex,则它还确保err是该类的实例,或者确保消息与正则表达式匹配。 该行为与磁带的throws断言相同。 例子 假设delay()返回一个承诺: const test = requi

    Python核心编程第二版(ok)

     11.3.3 前向引用   11.3.4 函数属性   11.3.5 内部内嵌函数   11.3.6 函数(与方法)装饰器   11.4 传递函数   11.5 FormalcArguments   11.5.1 位置参数   11.5.2 默认参数   11.6 可变...

Global site tag (gtag.js) - Google Analytics