go 正则表达式分组匹配 |
您所在的位置:网站首页 › 匹配多个空格的正则表达式是 › go 正则表达式分组匹配 |
分组的引入: 对于要重复单个字符,非常简单,直接在字符后卖弄加上限定符即可,例如 a+ 表示匹配1个或一个以上的a,a?表示匹配0个或1个a。这些限定符如下所示: X? X,一次或一次也没有 X* X,零次或多次 X+ X,一次或多次 X{ n } X,恰好n次 X{ n ,} X,至少n次 X{ n , m } X,至少n次,但是不超过m次 但是我们如果要对多个字符进行重复怎么办呢?此时我们就要用到分组,我们可以使用小括号"()"来指定要重复的子表达式,然后对这个子表达式进行重复,例如:(abc)? 表示0个或1个abc 这里一 个括号的表达式就表示一个分组 。 分组可以分为两种形式,捕获组和非捕获组。 一、捕获组 捕获组可以通过从左到右计算其开括号来编号 。例如,在表达式 (A)(B(C)) 中,存在四个这样的组: 0 (A)(B(C)) 1 (A) 2 (B(C)) 3 (C) 组零始终代表整个表达式 之所以这样命名捕获组是因为在匹配中,保存了与这些组匹配的输入序列的每个子序列。捕获的子序列稍后可以通过 Back 引用(反向引用) 在表达式中使用,也可以在匹配操作完成后从匹配器检索。 Back 引用 是说在后面的表达式中我们可以使用组的编号来引用前面的表达式所捕获到的文本序列。注意:反向引用,引用的是前面捕获组中的文本而不是正则,也就是说反向引用处匹配的文本应和前面捕获组中的文本相同,这一点很重要。 【例】(["']).*\1 其中使用了分组,\1就是对引号这个分组的引用,它匹配包含在两个引号或者两个单引号中的所有字符串,如,"abc" 或 " ' " 或 ' " ' ,但是请注意,它并不会对" a'或者 'a"匹配。原因上面已经说明,Back引用只是引用文本而不是表达式。 分组举列 先来看第一个作用,对于IP地址的匹配,简单的可以写为如下形式: \d{1,3}.\d{1,3}.\d{1,3}.\d{1,3} 但仔细观察,我们可以发现一定的规律,可以把.\d{1,3}看成一个整体,也就是把他们看成一组,再把这个组重复3次即可。表达式如下: \d{1,3}(.\d{1,3}){3} 再来看第二个作用,就拿匹配 xxx标签来说,简单的正则可以这样写:.*可以看出,上边表达式中有两个title,完全一样,其实可以通过分组简写。表达式如下: .*\1> 对于分组而言,整个表达式永远算作第0组,在本例中,第0组是.*\1>,然后从左到右,依次为分组编号,因此,(title)是第1组。 注意: 用\1这种语法,可以引用某组的文本内容,但不能引用正则表达式。 例如刚刚的IP地址正则表达式为\d{1,3}(.\d{1,3}){3},里边的\d{1,3}重复了两次,如果利用后向引用简化,表达式如下: (\d{1,3})(.\1){3} 经过实际测试,会发现这样写是错误的,为什么呢? 后向引用,引用的仅仅是文本内容,而不是正则表达式! 也就是说,组中的内容一旦匹配成功,后向引用,引用的就是匹配成功后的内容,引用的是结果,而不是表达式。 因此,(\d{1,3})(.\1){3}这个表达式实际上匹配的是四个数都相同的IP地址,比如:123.123.123.123。 二、非捕获组 以 (?) 开头的组是纯的非捕获 组,它不捕获文本 ,也不针对组合计进行计数。就是说,如果小括号中以?号开头,那么这个分组就不会捕获文本,当然也不会有组的编号,因此也不存在Back 引用。 我们通过捕获组就能够得到我们想要匹配的内容了,那为什么还要有非捕获组呢?原因是捕获组捕获的内容是被存储在内存中,可供以后使用,比如反向引用就是引用的内存中存储的捕获组中捕获的内容。而非捕获组则不会捕获文本,也不会将它匹配到的内容单独分组来放到内存中。所以,使用非捕获组较使用捕获组更节省内存。在实际情况中我们要酌情选用。 1、非捕获组(?:Pattern) 它的作用就是匹配Pattern字符,好处就是不捕获文本,不将匹配到的字符存储到内存中,从而节省内存。 【例】匹配indestry或者indestries 我们可以使用indestr(y|ies)或者indestr(?:y|ies) 【例】(?:a|A)123(?:b)可以匹配a123b或者A123b 非捕获组有很多种形式,其中包括:零宽度断言和模式修正符 2、零宽度断言 (?= X ) X,通过零宽度的正lookahead 字符串:product_path 正则:(product)(?=_path) 结果:product (?! X ) X,通过零宽度的负lookahead 字符串:product_path 正则:(product)(?!_url) 结果:product 字符串:product_path 正则:(product)(?!_path) 结果:空 (? Match (单匹配项 内容) –> GroupCollection (单匹配项中包含的 "(分组/子表达式项)" 集合) –> Group ( "(分组/子表达式项)" 内容) –> CaputerCollection (分组项内容显示基础?) –> Caputer Group 对分组有两种访问方式: 1、数组下标访问 在 ((\d+)([a-z]))\s+ 这个正则表达式里总共包含了四个分组,按照默认的从左到右的匹配方式, Groups[0] 代表了匹配项本身,也就是整个整个表达式 ((\d+)([a-z]))\s+ Groups[1] 代表了子表达式项 ((\d+)([a-z])) Groups[2] 代表了子表达式项 (\d+) Groups[3] 代表了子表达式项 ([a-z]) string text = "1A 2B 3C 4D 5E 6F 7G 8H 9I 10J 11Q 12J 13K 14L 15M 16N ffee80 #800080"; Response.Write(text+ "");string strPatten = @"((\d+)([a-z]))\s+"; Regex rex= newRegex(strPatten, RegexOptions.IgnoreCase); MatchCollection matches=rex.Matches(text);//提取匹配项 foreach (Match match inmatches) { GroupCollection groups=match.Groups; Response.Write(string.Format("{0} 共有 {1} 个分组:{2}", match.Value, groups.Count, strPatten));//提取匹配项内的分组信息 for (int i = 0; i < groups.Count; i++) { Response.Write(string.Format("分组 {0} 为 {1},位置为 {2},长度为 {3}", i , groups[i].Value , groups[i].Index , groups[i].Length)); } }/** 输出: 1A 2B 3C 4D 5E 6F 7G 8H 9I 10J 11Q 12J 13K 14L 15M 16N ffee80 #800080 1A 共有 4 个分组:((\d+)([a-z]))\s+ 分组 0 为 1A ,位置为 0,长度为 3 分组 1 为 1A,位置为 0,长度为 2 分组 2 为 1,位置为 0,长度为 1 分组 3 为 A,位置为 1,长度为 1 ....*/ 2、命名访问 利用 (?子表达式) 定义分组别名,这样就可以利用 Groups["xxx"] 进行访问分组/子表达式内容。 string text = "I've found this amazing URL at http://www.sohu.com, and then find ftp://ftp.sohu.comisbetter."; Response.Write(text+ "");string pattern = @"\b(?\S+)://(? \S+)\b";Response.Write(pattern.Replace("", ">") + ""); MatchCollection matches=Regex.Matches(text, pattern);foreach (Match match inmatches) { GroupCollection groups=match.Groups; Response.Write(string.Format("URL: {0}; Protocol: {1}; Address: {2} ", match.Value , groups["protocol"].Value , groups["address"].Value)); }/** 输出 I've found this amazing URL athttp://www.sohu.com, and then find ftp://ftp.sohu.comisbetter. \b(?\S+)://(? \S+)\bURL:http://www.sohu.com; Protocol: http; Address: www.sohu.com URL: ftp://ftp.sohu.comisbetter; Protocol: ftp; Address: ftp.sohu.comisbetter*/ 内容参考自: |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |