正则表达式、分组、子匹配(子模式)、非捕获子匹配(子模式)

前面我们知道正则表达式有很多元字符表示匹配次数(量词),都是可以重复匹配前面出现的单个字符次数。有时候,我们可能需要匹配一组多个字符一起出现的次数。这个时候,我们需要分组了。就是用小括号来括起这些字符,指定子表达式(也叫做分组)。然后你就可以指定这个子表达式的重复次数了,你也可以对子表达式进行其它一些操作。这个时候,可以把括号中一组字符,看作一个整体了。

分组模式举例说明

如:查找字符串中,连续出现多个win字符串的字符。可以这样完

<?php
$str = "this is win winwindows!";
preg_match_all("/(win)+/",$str,$marr);
var_dump($marr);

不用分组模式,同时匹配多个字符,可以吗? 我们发现以前操作符号:[win]+,尽管可以匹配到winwin字符,因为它代表是有w,i,n组合的一个或者多个字符,不会限制顺序。所见它会匹配到象:wwin,www,inw等等,只要是这3个字符组成的,多个字符都匹配成功了。

上面怎么匹配到,每一个有2个结果呢?这就是子模式(子匹配),默认除了可以将多个字符组合一个整体,另外还会把括号,括起来的这部分表达式存储到一个临时缓冲区中,以便后面正则表达式调用。上面这个例子里面,我们不需要,后期调用的。因此,怎么样屏蔽掉这个子表达式捕获内容呢? 只需要在:前加上”?:” 即可。我们看看下面例子正则表达式 分组非捕获模式。

非捕获模式优点有哪些呢? 从上面看,可以减少捕获,也就会减少匹配次数。因此,在不必要分组表达式加入非捕获前缀”?:”,可以节省内存开销,并且可以提升匹配速度!

刚刚说到了正则表达式分组,默认情况会将子表达式捕获内容,存储到一个缓存区。以便后续调用。 那这个是什么样情况呢?其实,这个是正则表达式的引用。所捕获的每个子匹配都按照在正则表达式模式中从左至右所遇到的内容按顺序存储。存储子匹配的缓冲区编号从1开始,最多可以一般存储为9。以便后面表达式引用该值,又叫后向引用。

我们看下下面例子,查找一个字符串中,互不相邻,出现多次系统单词:add。

<?php
$str = "add123456addasdf";
preg_match_all('/(add)\d+\1/',$str,$marr);
var_dump($marr);

反向引用,常用来处理一些处理一些特殊匹配情况。如:查找字符串中,不相邻重复字符串。查找html一对标签中内容。特别分析html非常常见了(注意,如果使用了反向引用,前面不能屏蔽子匹配捕获,也就是不能加”?:"前缀了)。经常会用:

<?php
$str = file_get_contents('http://blog.chacuo.net/');
preg_match_all('/<(\S+)[^>]*>[^<]*<\/\1>/',$str,$marr);

var_dump($marr);

// (\S+) 表示非显示字符之外所有字符,一般作为html tag名称
// tag格式一般为 <tag  其它属性> 后面[^>]* 匹配tag里面所有其它属性
// 后面的[^<]* 表示 <tag...>中间内容</tag> 表示中间内容,到"<"结束,因此匹配所有[^<]* 字符
// 最后的<\/\1> "\/" 转义"/"字符,后面的"\1" 表示反向应用前面的(\S+)

以上是正则表达式使用比较重要的,分组,反向匹配,以及非捕获分组说明及实例。希望对要属性改功能朋友有所帮助。同时欢迎朋友们交流!

(0)

相关推荐

  • JS正则表达式获取分组内容的方法详解

    支持多次匹配的方式: 复制代码 代码如下: var testStr = "now test001 test002";   var re = /test(\d+)/ig;    var r = "";   while(r = re.exec(testStr)) {       alert(r[0] + "  " + r[1]);   } 此外也可以用testStr.match(re),但是这样的话就不能有g的选项,而且只能得到第一个匹配. 另外备忘

  • 浅谈JavaScript正则表达式-非捕获性分组

    非捕获性分组定义子表达式可以作为整体被修饰但是子表达式匹配结果不会被存储. 非捕获性分组通过将子表达式放在"?:"符号后. str = "img1.jpg,img2.jpg,img3.bmp"; reg = /(?:\w*)(?=\.gif)/; arr_m = str.match(reg);//arr_m = ["img1","img2"] 你在期待什么还是在等待什么?你选择了什么还是只想浮徒一生?茫茫人海,真的需要那么回眸

  • JavaScript正则表达式的分组匹配详解

    分组 下面的正则表达式可以匹配kidkidkid: /kidkidkid/ 而另一种更优雅的写法是: /(kid){3}/ 这里由圆括号包裹的一个小整体称为分组. 候选 一个分组中,可以有多个候选表达式,用|分隔: var reg = /I love (him|her|it)/; reg.test('I love him') // true reg.test('I love her') // true reg.test('I love it') // true reg.test('I love

  • JS正则表达式之非捕获分组用法实例分析

    本文实例讲述了JS正则表达式非捕获分组用法.分享给大家供大家参考,具体如下: 最近在看JsonSQL的时候,通过源码中的一段正则表达式,了解到了什么是非捕获分组以及它的使用场景.在js中,正常的捕获分组格式是(XX),非捕获分组格式为(?:XX).我们先从正则表达式数量词说起,如果我们要求字符b至少出现一次,可以使用正则/b+/:如果要求ab至少出现一次,那么必需使用/(ab)+/,不能用/ab+/.也就是说,如果想对多个字符使用数量词,必需要用圆括号. var str = "a1***ab1c

  • javascript正则表达式中分组详解

    之前写了一篇关于正则新手入门的文章,本以为对正则表达式相对比较了解 但是今天我又遇到了一个坑,可能是自己不够细心的原因吧,今天就着重和大家分享一下javascript正则表达式中的分组.如果你对JS正则表达式不够理解 可以点击这里了解更多. 分组在正则中用的还是比较广的,我所理解的分组 就是一对括号() ,每一对括号 就代表了一个分组, 分组可以分为: 捕获性分组 非捕获性分组 捕获性分组 捕获性分组会在 比如 match exec这样的函数中以第二项,第三项的形式得到相应分组的结果.先来看一个

  • 正则表达式之捕获组/非捕获组介绍

    捕获组 语法: 字符  描述 示例 (pattern) 匹配pattern并捕获结果,自动设置组号. (abc)+d 匹配abcd或者abcabcd (?<name>pattern) 或 (?'name'pattern) 匹配pattern并捕获结果,设置name为组名. \num 对捕获组的反向引用.其中 num 是一个正整数. (\w)(\w)\2\1 匹配abba \k< name > 或 \k' name ' 对命名捕获组的反向引用.其中 name 是捕获组名. (?<

  • 正则表达式、分组、子匹配(子模式)、非捕获子匹配(子模式)

    前面我们知道正则表达式有很多元字符表示匹配次数(量词),都是可以重复匹配前面出现的单个字符次数.有时候,我们可能需要匹配一组多个字符一起出现的次数.这个时候,我们需要分组了.就是用小括号来括起这些字符,指定子表达式(也叫做分组).然后你就可以指定这个子表达式的重复次数了,你也可以对子表达式进行其它一些操作.这个时候,可以把括号中一组字符,看作一个整体了. 分组模式举例说明 如:查找字符串中,连续出现多个win字符串的字符.可以这样完 <?php $str = "this is win wi

  • js正则表达式之前瞻后顾与非捕获分组

    目录 前瞻后顾与捕获分组的结合使用 捕获分组与非捕获分组 前瞻.后顾与负前瞻.负后顾 总结 前瞻后顾与捕获分组的结合使用 在现实的应用场景中,捕获分组或非捕获分组通常被限制在前瞻后顾条件内,举例来说,对数字12345678格式化,结果为12,345,678.其正则实现如下: let formatSum = '12345678'.replace(/\B(?=(?:\d{3})+(?!\d))/g, ',') 捕获分组与非捕获分组 为了理解前瞻与后顾,首先要先理解捕获分组与非捕获分组 在js中, (

  • PHP实现正则表达式分组捕获操作示例

    本文实例讲述了PHP实现正则表达式分组捕获操作.分享给大家供大家参考,具体如下: 经过测试,发现php正则表达式获取分组捕获是从$0开始,而平时工作中JavaScript中的正则是$1..$9 在提取项目代码中的汉字时,因为当时操作速度很快(赶时间),很担心当时.properties的文件{\d}的数字顺序搞错了: 1.可能从{1}开始,而不是从{0}开始 2.可能跳着写了,比如第一个是{0}第二个需要替换的地方却写着{2} 因为使用人工手动操作的,所以这种情况是难以避免,只能说减少误操作.写完

  • PHP之正则表达式捕获组与非捕获组(详解)

    在项目开发过程中正则表示经常会用到,可以说会正则表达式是每个程序员最基本的要求,初学者在刚接触正则表达式都感到很吃力.最近看到一位朋友的博客写的<PHP正则表达式>获益颇多,在章节对通配符以及捕获数据非常感兴趣.这两章节刚好也涉及到了正则表达式的捕获组和非捕获组的内容,以此来分析这方面的内容 我们知道,在正则表达式下(x) 表示匹配'x'并记录匹配的值.这只是比较通俗的说法,甚至说这是不严谨的说法,只有()捕获组形式才会记录匹配的值.非捕获组则只匹配,不记录. 捕获组: (pattern) 这

  • java多线程编程之捕获子线程异常示例

    通过try catch是无法捕获子线程异常的,Thread对象提供了setUncaughtExceptionHandler(Thread.UncaughtExceptionHandler eh)方法用来获取线程中产生的异常. 复制代码 代码如下: package threads; import java.lang.Thread.UncaughtExceptionHandler; public class TextException{  public static void main(String

  • JavaScript正则表达式的贪婪匹配和非贪婪匹配

    所谓贪婪匹配就是匹配重复字符是尽可能多的匹配,比如: "aaaaa".match(/a+/); //["aaaaa", index: 0, input: "aaaaa"] 非贪婪匹配就是尽可能少的匹配,用法就是在量词后面加上一个"?",比如: "aaaaa".match(/a+?/); //["a", index: 0, input: "aaaaa"] 但是非贪婪匹配

  • PHP正则表达式之捕获组与非捕获组

    今天遇到一个正则匹配的问题,忽然翻到有捕获组的概念,手册上也是一略而过,百度时无意翻到C#和Java中有对正则捕获组的特殊用法,搜索关键词有PHP时竟然没有相关内容,自己试了一下,发现在PHP中也是可行的,于是总结一下,分享的同时也希望有大神和细心的学习者找到我理解中出现的问题. 什么是捕获组 捕获组语法: 字符  描述 示例 (pattern) 匹配pattern并捕获结果,自动设置组号. (abc)+d 匹配abcd或者abcabcd (?<name>pattern) 或 (?'name'

随机推荐