c# 正则表达式regex心得
5.1. C#中的正则表达式的简介 C#中的Regex类处理正则表达式。 5.2. C#正则表达式的语法 5.3. C#中的正则表达式的特点 下面总结一些C#中的正则表达式相对于其他语言中的正则表达式的一些特点,包括优点和缺点: 可以一次性的即搜索多个匹配的整个的字符串,同时又可以一次性地,对于每个字符串,在给定Regex的时候,就分组group,然后得到macthes之后,foreach处理每个match,已经可以得到对应的匹配的结果,可以使用不同group的值了。还是很方便的。
对于匹配多个字符串的时候,好像不能加括号分组的,如果加括号分组了,那么只能匹配单个一个group就结束了。对应的要匹配多个字符串,好像只能使用findall。
5.4. C#正则表达式的使用心得或注意事项 5.4.. 正则表达式字符串的写法 正则表达式是用字符串前面加上@字符来表示的。 5.4.. 正则表达式中包含双引号,是用两个双引号去表示 其中如果包含的字符串中包含双引号,那么就两个双引号表示,而不是反斜杠加上双引号(\”),也不是斜杠加上双引号(/”) 示例代码: string pat = @"var\s+primedResponse=\{""items""\:\[\{(.*)}\]\};\s+\$Do\.register\(""primedResponse""\);";
Regex rx = new Regex(pat,RegexOptions.Compiled); 5.4.. C#中的named group和后向引用 C#中,对于前面所匹配的字符组名的替换和(向后)引用,是不一样的 替换是这样的写法:${name} 而向后引用是这样的写法:\k<name> 5.4.. 关于字符点,匹配任意字符,但是不匹配换行(\n)的事情 一般对于介绍正则表达式的时候,为了简便,都说成字符点(.),是匹配任何单个字符的。 有的解释的严谨的,也会加上一句,在非单行匹配模式下,匹配除了换行\n之外的任意字符。 此句话有更深层的含义: 5.4.4.1. 关于默认情况下就是非单行模式,所以默认情况,点是不匹配换行字符\n的 一般来说,调用的正则表达式的库函数,比如C#中的用new Regex生成对应的Regex变量的时候: Regex imgRx = new Regex(imgP);
MatchCollection foundImg = imgRx.Matches(curSelectCotent); 默认就是多行模式,所以如果像我这里,如果去匹配的内容,涉及到中间包括\n字符,那么默认情况下,是无法匹配的, 导致程序调试花了半天时间,才找到上述原因。 例 5.1. 默认的点'.'不匹配换行\n 对于一堆字符: <P><A
href="file:///C:/Users/CLi/AppData/Local/Temp/WindowsLiveWriter1627300719/supfiles6977DF/F200908260947322978810268[2].jpg"><IMG
style="BACKGROUND-IMAGE: none; BORDER-BOTTOM: 0px; BORDER-LEFT: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; DISPLAY: inline; BORDER-TOP: 0px; BORDER-RIGHT: 0px; PADDING-TOP: 0px"
title=F200908260947322978810268 border= alt=F200908260947322978810268
src="file:///C:/Users/CLi/AppData/Local/Temp/WindowsLiveWriter1627300719/supfiles6977DF/F200908260947322978810268_thumb.jpg"
width= height=></A> </P>
<P><A
href="file:///C:/Users/CLi/AppData/Local/Temp/WindowsLiveWriter1627300719/supfiles6977DF/王珞丹 图片22[3].jpg"><IMG
style="BACKGROUND-IMAGE: none; BORDER-BOTTOM: 0px; BORDER-LEFT: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; DISPLAY: inline; BORDER-TOP: 0px; BORDER-RIGHT: 0px; PADDING-TOP: 0px"
title="王珞丹 图片22" border= alt="王珞丹 图片22"
src="file:///C:/Users/CLi/AppData/Local/Temp/WindowsLiveWriter1627300719/supfiles6977DF/王珞丹 图片22_thumb.jpg"
width= height=></A><A
href="file:///C:/Users/CLi/AppData/Local/Temp/WindowsLiveWriter1627300719/supfiles6977DF/王珞丹 图片333[2].jpg"><IMG
style="BACKGROUND-IMAGE: none; BORDER-BOTTOM: 0px; BORDER-LEFT: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; DISPLAY: inline; BORDER-TOP: 0px; BORDER-RIGHT: 0px; PADDING-TOP: 0px"
title="王珞丹 图片333" border= alt="王珞丹 图片333"
src="file:///C:/Users/CLi/AppData/Local/Temp/WindowsLiveWriter1627300719/supfiles6977DF/王珞丹 图片333_thumb.jpg"
width= height=></A></P> 然后用下面的代码去匹配: string imgP = @"href=""(file:.+?WindowsLiveWriter.+?)"".+?src=""(file:.+?WindowsLiveWriter.+?)""";
Regex imgRx = new Regex(imgP);
MatchCollection foundImg = imgRx.Matches(curSelectCotent); 则其中的"".+?src=""中的.+?是无法匹配成功的,因为上述输入的字符串中,包括了换行符,导致此处无法匹配。 而只有把 Regex imgRx = new Regex(imgP);
改为: Regex imgRx = new Regex(imgP, RegexOptions.Singleline);
才是可以的。 即设置为单行模式,此处点(.)就匹配,包括\n在内的任意单个字符了。 其他语言中,比如Python等,也有对应的single line,multi line等方面的设置,可根据自行需要设置。 5.4.4.2. 匹配换行\n之外的任意字符,那么也包括了回车\r字符 所以,万一你的应用中,需要涉及到这个字符,(如果不是单行模式的话),要注意的是点(.)是匹配\r,但不匹配\n的。 5.4.. C#中如何获得带名字name的捕获capture的组group 对于输入字符串为: <A
href="file:///C:/Users/CLi/AppData/Local/Temp/WindowsLiveWriter1627300719/supfiles111AD15/王珞丹 图片22[3].jpg"><IMG
style="BACKGROUND-IMAGE: none; BORDER-BOTTOM: 0px; BORDER-LEFT: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; DISPLAY: inline; BORDER-TOP: 0px; BORDER-RIGHT: 0px; PADDING-TOP: 0px"
title="王珞丹 图片22" border= alt="王珞丹 图片22"
src="file:///C:/Users/CLi/AppData/Local/Temp/WindowsLiveWriter1627300719/supfiles111AD15/王珞丹 图片22_thumb.jpg"
width= height=></A> 用下面的代码: string imgP = @"href=""(file:///(?<localAddrPref>.+?WindowsLiveWriter.+?/supfile[^/]+?)/(?<realName>[^""]+?)\[\d+\](\.(?<suffix>\w{3,4}))?)"".+?src=""(file:///\k<localAddrPref>/\k<realName>_thumb(\.\k<suffix>)?)""";
Regex imgRx = new Regex(imgP, RegexOptions.Singleline);
MatchCollection foundImg = imgRx.Matches(curSelectCotent); 是可以获得所匹配的group的,但是想要对应带名字的的那些变量,比如localAddrPref,suffix等值,却不知道如何获得。 其实,根据Grouping Constructs的解释,也已经知道如何可以获得,只是觉得那种方法不够好,希望可以找到对应的capture对应的自己的处理方法。 后来找了下,参考Regex: Named Capturing Groups in .NET才明白,原来对于带名字的匹配的group,其实也是group,但是是对于每一个match来说,都有对应的自己的capture的。 结果去试了试,发现如果写成这样: CaptureCollection captures = found.Captures;
localAddrPref = captures[].Value;
title = captures[].Value; // will lead to code run dead ! captures[]是整个的字符串,而不是对应的第一个name group的值,而captures[],则直接导致程序死掉,即不能这样调用。 另外,在Regex: get the name of captured groups in C#也找到了用GetGroupNames的方式,有空也去试试。 看到Regular Expression Classes解释的,可以直接用groupname取得对应的值的,即之前都是用found.Groups[].ToString()而换作found.Groups["localAddrPref"].Value即可。 其中localAddrPref是前面的某个group的name。 5.4.. C#中,对于Regex中带嵌套的括号,那么group是的index如何计算,以及Regex中包含了带name的group,group又是如何计算的。 此处的逻辑,是根据官方的解释加上实际调试所得到的结果,来解释说明的。 举例,对于输入字符串: <A
href="file:///C:/Users/CLi/AppData/Local/Temp/WindowsLiveWriter1627300719/supfiles111AD15/王珞丹 图片22[3].jpg"><IMG
style="BACKGROUND-IMAGE: none; BORDER-BOTTOM: 0px; BORDER-LEFT: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; DISPLAY: inline; BORDER-TOP: 0px; BORDER-RIGHT: 0px; PADDING-TOP: 0px"
title="王珞丹 图片22" border= alt="王珞丹 图片22"
src="file:///C:/Users/CLi/AppData/Local/Temp/WindowsLiveWriter1627300719/supfiles111AD15/王珞丹 图片22_thumb.jpg"
width= height=></A> 用这样的代码去匹配: string imgP = @"href=""file:///((?<localAddrPref>.+?WindowsLiveWriter.+?/supfile[^/]+?)/(?<realName>[^""]+?)\[\d+\](\.(?<suffix>\w{3,4}))?)"".+?title=""?(\k<realName>)?""?.+?alt=""?(\k<realName>)?""?.+?src=""file:///(\k<localAddrPref>/\k<realName>_thumb(\.\k<suffix>)?)""";
Regex imgRx = new Regex(imgP, RegexOptions.Singleline);
MatchCollection foundImg = imgRx.Matches(curSelectCotent); 则匹配的结果是: _groups {System.Text.RegularExpressions.Group[]} System.Text.RegularExpressions.Group[]
[] {C:/Users/CLi/AppData/Local/Temp/WindowsLiveWriter1627300719/supfiles111AD15/王珞丹 图片22[].jpg} System.Text.RegularExpressions.Group
[] {.jpg} System.Text.RegularExpressions.Group
[] {王珞丹 图片22} System.Text.RegularExpressions.Group
[] {王珞丹 图片22} System.Text.RegularExpressions.Group
[] {C:/Users/CLi/AppData/Local/Temp/WindowsLiveWriter1627300719/supfiles111AD15/王珞丹 图片22_thumb.jpg} System.Text.RegularExpressions.Group
[] {.jpg} System.Text.RegularExpressions.Group
[] {C:/Users/CLi/AppData/Local/Temp/WindowsLiveWriter1627300719/supfiles111AD15} System.Text.RegularExpressions.Group
[] {王珞丹 图片22} System.Text.RegularExpressions.Group
[] {jpg} System.Text.RegularExpressions.Group 注意,上述内容是debug所查看到的。 group[]不是整个字符串,而是表示此处匹配的第一个结果,即index从0开始,而不是默认的1. 不过下面还是以代码中的写法来解释。 5.4.6.1. C#中,如果Regex中包括了子括号,即括号嵌套括号的时候,group的index是如何计算的,以及如果Regex中包括了带name的group,group的index是如何计算的 搞了半天,最后终于看懂了。 现在来说说,如何数group的index。 其实很简单: 首先,所有的group,分两类,一类是默认的,无名字(unnamed的group),另外一类是有名字的group(name的group)。
然后对于group的index,从左至右,以左括号出现的位置先后为标准,一个个的数一下对应的unnamed的group,等全部数完了,再去安装同样标准去数有名字的group。
或者可以完全不去数有name的group,因为有name的group的值,完全可以直接通过Groups["yorGroupName"].Value的形式得到。
举例说明: 对于例子中的匹配样式: href=""file:///((?<localAddrPref>.+?WindowsLiveWriter.+?/supfile[^/]+?)/(?<realName>[^""]+?)\[\d+\](\.(?<suffix>\w{3,4}))?)"".+?title=""?(\k<realName>)?""?.+?alt=""?(\k<realName>)?""?.+?src=""file:///(\k<localAddrPref>/\k<realName>_thumb(\.\k<suffix>)?)"" 从左往右,第一个是file:///后面的左括号,即对应的括号是?)"".+?title中的这个右括号, 由于其是unnamed的group,所以代码中的index为第一个,为1, 对应着代码和值是: Groups[].ToString() == 上述调试的结果 C:/Users/CLi/AppData/Local/Temp/WindowsLiveWriter1627300719/supfiles111AD15/王珞丹 图片22[].jpg 然后再往右数,第二个括号是(?<localAddrPref>中的左括号,对应右括号是+?)/(?<realName>中的右括号, 由于其实有名字的group,所以对应的index,不是Groups[],而是等最后数完了全部的unnamed的group,才能知道此处的index。 但是由于是有名字的,所以也是可以直接通过group的name来获得对应的值的。 对应的代码和值是: Groups["localAddrPref"] == C:/Users/CLi/AppData/Local/Temp/WindowsLiveWriter1627300719/supfiles111AD15 然后按照此法: 从左往右,依次按照左括号出现的先后顺序去数,得到对应的各个group是: 第一个: ((?<localAddrPref>.+?WindowsLiveWriter.+?/supfile[^/]+?)/(?<lrealName>[^""]+?)\[\d+\](\.(?<lsuffix>\w{,}))?)
unnamed index为1,值为Groups[].ToString() 第二个: (?<localAddrPref>.+?WindowsLiveWriter.+?/supfile[^/]+?)
有名字,index待定,值为Groups["localAddrPref"].Value 第三个: (?<realName>[^""]+?)
有名字,index待定,值为Groups["realName"].Value 第四个: (\.(?<suffix>\w{,}))
unnamed,index为2,值为Groups[].ToString() 第五个:(?<suffix>\w{,})
有名字,index待定,值为Groups["suffix"].Value 第六个: (\k<realName>)
unnamed,index为3,值为Groups[].ToString() 第七个: (\k<realName>)
unnamed,index为4,值为Groups[].ToString() 第八个: (\k<localAddrPref>/\k<realName>_thumb(\.\k<suffix>)?)
unnamed,index为5,值为Groups[].ToString() 第九个: (\.\k<suffix>)
unnamed,index为6,值为Groups[].ToString() 对照着上述debug出来的结果,正好分别就是: Groups[].ToString() == debug中的[] == C:/Users/CLi/AppData/Local/Temp/WindowsLiveWriter1627300719/supfiles111AD15/王珞丹 图片22[].jpg
Groups[].ToString() == debug中的[] == .jpg
Groups[].ToString() == debug中的[] == 王珞丹 图片22
Groups[].ToString() == debug中的[] == 王珞丹 图片22
Groups[].ToString() == debug中的[] == C:/Users/CLi/AppData/Local/Temp/WindowsLiveWriter1627300719/supfiles111AD15/王珞丹 图片22_thumb.jpg
Groups[].ToString() == debug中的[] == .jpg
而unnamed的全部都数完了,然后才是从左到右的,有名字的index依次增加,以及对应的值是: Groups["localAddrPref"].Value == Groups[].ToString() == debug中的[] == C:/Users/CLi/AppData/Local/Temp/WindowsLiveWriter1627300719/supfiles111AD15
Groups["realName"].Value == Groups[].ToString() == debug中的[] == 王珞丹 图片22
Groups["suffix"].Value == Groups[].ToString() == debug中的[] == jpg
所以,对于Regex中的group和named的group的index如何计算,就是上面那一句话: 从左到右,以左括号出现位置先后为顺序,index一次增加。 先全部数完unnamed的group,再去数有name的group,其中有name的group,完全可以不去计算对应的index是多少的,因为可以直接通过名字来引用对应的值,用法为: Groups["yorGroupName"].Value
c# 正则表达式regex心得的更多相关文章
- C#正则表达式Regex常用匹配
使用Regex类需要引用命名空间:using System.Text.RegularExpressions; 利用Regex类实现验证 示例1:注释的代码所起的作用是相同的,不过一个是静态方法,一个是 ...
- C#正则表达式Regex类的用法
C#正则表达式Regex类的用法 更多2014/2/18 来源:C#学习浏览量:36891 学习标签: 正则表达式 Regex 本文导读:正则表达式的本质是使用一系列特殊字符模式,来表示某一类字符串, ...
- C#正则表达式Regex类
C#正则表达式Regex类的使用 C#中为正则表达式的使用提供了非常强大的功能,这就是Regex类.这个包包含于System.Text.RegularExpressions命名空间下面,而这个命名空间 ...
- (四)boost库之正则表达式regex
(四)boost库之正则表达式regex 正则表达式可以为我们带来极大的方便,有了它,再也不用为此烦恼 头文件: #include <boost/regex.hpp> 1.完全匹配 std ...
- boost 正则表达式 regex
boost 正则表达式 regex 环境安装 如果在引用boost regex出现连接错误,但是引用其他的库却没有这个错误,这是因为对于boost来说,是免编译的,但是,正则这个库 是需要单独编译 ...
- 请写出正则表达式(regex),取得下列黄色部分的字符串 TEL: 02-236-9655/9659 FAX:02-236-9654 (黄色部分即02-236-9655/9659 ) ( 测试面试题)
请写出正则表达式(regex),取得下列黄色部分的字符串 TEL: 02-236-9655/9659 FAX:02-236-9654 答: package test1; import java.uti ...
- Python 正则表达式(RegEx)
版权所有,未经许可,禁止转载 章节 Python 介绍 Python 开发环境搭建 Python 语法 Python 变量 Python 数值类型 Python 类型转换 Python 字符串(Str ...
- C#正则表达式Regex类使用
作为文本处理的利器——Perl语言对正则表达式的最强大支持起到了重要的作用,正因为如此,许多其他语言在加入正则表达式引擎的时候都会或多或少的兼顾perl风格的正则表达式,开发出相应的引擎.本人使用pe ...
- Golang 正则表达式Regex相关资料整理
Golang 支持的正在表达式是 https://github.com/google/re2/wiki/Syntax 注意这里提示 NOT SUPPORTED的。 工具 一些测试正则表达式的工具 推荐 ...
随机推荐
- AI:PR的数学表示-传统方法PR
前言: 接上一篇:AI:模式识别的数学表示 在图像处理PR领域,相对于ANN方法,其他的方法一般称为传统方法.在结构上,几乎所有的PR方法都是可解释的.且任一传统方法,在一定约束下,可以转换为SV近邻 ...
- 解决JavaOpenCV的内存问题
在使用OpenCV时,程序总是在某个时间墨明棋妙地终止,打开CygWin ,输入 adb logcat ,查看打印的信息,发现是内存问题.经过反复的查找,发现使用OpenCV的java类库时,一定要慎 ...
- 【sqli-labs】 less39 GET -Stacked Query Injection -Intiger based (GET型堆叠查询整型注入)
http://192.168.136.128/sqli-labs-master/Less-39/?id=1;insert into users(id,username,password) values ...
- (转)Arcgis for Js之鼠标经过显示对象名的实现
http://blog.csdn.net/gisshixisheng/article/details/41889345 在浏览地图时,移动鼠标经过某个对象或者POI的时候,能够提示该对象的名称对用户来 ...
- Java中StringTokenizer类的使用
StringTokenizer是一个用来分隔String的应用类,相当于VB的split函数. 1.构造函数 public StringTokenizer(String str) public Str ...
- 记录:Ubuntu下安装SQL Developer
安装JDK. 用的Ubuntu18.04,已经自带JDK了. 下载SQL Developer. 官网链接:http://www.oracle.com/technetwork/developer-too ...
- 【剑指Offer】32、把数组排成最小的数
题目描述: 输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个.例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323. ...
- nyoj29-求置转换问题
求转置矩阵问题 时间限制:3000 ms | 内存限制:65535 KB 难度:2 描述 求一个三行三列的转置矩阵. 输入 第一行一个整数n<20,表示有n组测试数据,下面是n组数据;每组测 ...
- Linux系统学习之 二:新手必须掌握的Linux命令2
2018-10-03 22:20:48 一.文件目录管理命令 1.touch 命令 用于创建空白文件或设置文件的时间,格式为“touch [选项] [文件]”. 参数: -a :仅修改“读取时间(at ...
- firebird数据库建模
用ERS数据库建模,真的很方便.可是8.0版本只支持interbase和ib2007.没有建模工具,查找修改数据库等确实是裹足难走.新的建模工具不适应.找来找去,新版10.0出来了.雷锋帮助把使用权也 ...