C#中的正则表达式双引号问题
其中如果包含的字符串中包含双引号,那么就两个双引号表示,而不是反斜杠加上双引号(\”),也不是斜杠加上双引号(/”)
正则表达式获取css里面的图片的例子,里面有url里面的图片地址有双引号,要注意用两个双引号""表示
static void main(string[] args) { regex reg = new regex(@"url\((['""]?)(.+[^'""])\1\)"); //注意里面的引号 要用双引号表示,而不是用反斜杠 console.writeline(reg.match(@"{background-image:url(//ssl.gstatic.com/ui/v1/menu/checkmark.png);backgro")); //输出 url(//ssl.gstatic.com/ui/v1/menu/checkmark.png) console.readkey(); }
带组名的后向引用在c#中是 \k<num> ,匹配重复单词的例子:
static void main(string[] args) { regex reg = new regex(@"\b(?<group>\w+ +)\k<group>"); string str = "what the hell are you you talking about?"; console.writeline(reg.match(str)); console.readkey(); }
在c#中new一个regex对象的时候,第二个参数能够用枚举支持选择匹配模式,现在就来说说这些枚举值对正则的影响。
模式 说明
.singleline 点号能够匹配任何字符
.multiline 扩展^和$的匹配,使^和$能够匹配字符串内部的换行符
.ignorepatternwhitespace 设计宽松排列和注释模式
.ignorecase 进行不区分大小写的匹配
.ecmascript 限制\w \s \d,令其只对ascii字符有效
.righttoleft 传动装置的驱动过程不变,但是方向相反(从字符的末尾开始,向开头移动)
.compiled 多花些时间优化正则表达式,编译到dll里,占用多点内存,但是匹配更快。
.explicitcapture 普通括号()在正常情况下是捕获型括号,但是在此模式下与(?:...)一样,之分组,不捕获
regexoptions.compiled的意义
使用regexoptions.compiled与不使用regexoptions.compiled的对比
标准 不使用 使用
启动速度 较快 较慢(最多60倍)
内存占用 少 多(每个正则表达式占用5-15kb)
匹配速度 一般 最多能提升10倍
在使用了regexoptons.compiled时,在程序执行过程中,这块内存会一直被占用,无法被释放,因此仅对于那些经常被使用的正则表达式才适合使用此选项。
ecmascript模式
要注意ecmascript只能与下面的选项同时使用
regexoptons.ignorecase
regexoptons.multiline
regexoptons.compiled
而且反斜线-数字不会有反向引用和十进制转移的二义性,因为它只能够表示反向引用。例如 \10 表示反向引用 \1 然后是文字0。如果没有启用该模式,则 \12 匹配的是ascii进纸符linefeed。同时\w \d \s \w \d \s只能匹配ascii。
另外在c#中,分组的编号也需要注意。
分组0是整个正则表达式匹配到的结果。
然后依次是未命名分组。
最后是命名分组。
例如:
(\w)(?<num>\d+)(\s+)
1 3 2
特殊的replacement处理
regex.replace方法和match.result方法都可以接收能够进行特殊处理的replacement字符串。下面的字符序列会被匹配到的文本所替换:
字符序列 替换内容
$& 整个表达式匹配的文本,相当于$0
$1 $2 对应编号的捕获分组所匹配的文本
${name} 对应命名捕获分组匹配的文本
$‘ 目标字符串中匹配文本之前的文本
$' 目标字符串中匹配文本之后的文本
$$ 单个$字符($1的显示为$$!)
$_ 正则原始目标字符串的副本
$+ .net中表示最后的那个捕获型括号匹配的文本
static void main(string[] args) { regex reg1 = new regex(@"\d+"); string str = reg1.replace("123","insert into table where id = $&"); console.writeline(str); //输出 insert into table where id = 123 regex reg2 = new regex(@"1\+1=(\d)"); string str2 = reg2.replace("1+1=3","不是$1"); console.writeline(str2); //输出 不是3 regex reg3 = new regex(@"1\+1=(?<result>\d)"); string str3 = reg3.replace("1+1=3", "不是${result}"); console.writeline(str3); //输出 不是3 regex reg4 = new regex(@"\d+"); string str4 = reg4.replace("123abc", "后面是$'"); //匹配文本之后的文本 console.writeline(str4); //输出 后面是abcabc 为什么会输出 后面是abcabc呢?因为$'指的是abc,然后替换掉原字符串中的123。不懂看多几次这句话 regex reg5 = new regex(@"\d+"); string str5 = reg5.replace("abc123", "前面是$`"); //abc前面是abc 符号是 1左边那个 console.writeline(str5); regex reg6 = new regex(@"\d+"); string str6 = reg6.replace("abc123","右边原始输入字符串$_"); console.writeline(str6); //输出 右边是原始字符串abc123 console.readkey(); }
关于.net中的正则装配件是用于构建正则表达式库的,保存在硬盘中,其他程序也能够调用,提高重用率。主要就是用到了regex类的compiletoassembly方法。
今天,碰到一个非常有趣的问题,公司多了个客户,产品那边说添加关键词太辛苦,让我帮忙批量导入一批关键词。哥这几天正好在研究正则表达式呢,于是二话不说,立马应了下来。一看,excel,算了npoi还没学呢。于是复制到txt文本里。
格式如下:
中山大道
粤垦路
.....
天助我也,难度不大,而且看来这几天学的东西有用武之地了。于是立马有了以下代码
static void main(string[] args) { string str = file.readalltext(@"d:\daoru.txt", encoding.default); regex reg = new regex(@".+"); string str1 = reg.replace(str, "insert into keyword values(196,'admin1','admin1','$&')"); file.writealltext(@"d:\123.txt", str1); console.readkey(); }
这是一个根据关键词生成sql语句的方法,从d盘导入txt文本(在这个地方,碰到一个问题,因为关键词是中文,所以直觉上觉得应该用utf-8编码去读,但是竟然出错了。于是上网查了一下,居然用encoding.default可以解决这个问题)。然后用正则表达式匹配到关键词。默认的new regex() 点号.是不会匹配换行符的,因此非常适合关键词一行一个的,例如从excel复制过来的时候。然后用regex类提供的replace将关键词替换成sql语句,直接黏贴到数据库上全选,执行。ok。一次过导入了近500个关键词。
本来以为正则表达式学得不错了,结果昨天替换的sql语句就出了问题,存入数据库的数据无缘无故多了个换行符。其实在执行sql语句的时候,sqlserver已经很尽职地给出提示了,可惜太大意或者说高兴得太早直接忽略了。来看昨天sql语句执行时的图片:
看到换行了吧,这样一来就会将在结果中多了个\r,在数据库表中还看不到,但是在用的时候,如果仅仅用于显示,也没问题,但是如果用来匹配,那就悲剧了。因此今天更改了程序。要将换行符替换掉。代码改为如下所示,其中改动部分红色标记:
static void main(string[] args) { string str = file.readalltext(@"d:\daoru.txt", encoding.default); regex reg = new regex(@".+"); string str1 = reg.replace(str, "insert into jm_sinablog_keyword values(105,'jmeii','jmeii','$&')").replace((char)13, (char)0);//here file.writealltext(@"d:\123.txt", str1); console.readkey(); }
这样一来,就替换掉换行符了。将生成的代码再复制到sqlserver里,可以看到sqlserver的显示变了:
这样就没问题了,以后在写正则表达式时要对换行,空格非常敏感才行。
上一篇: C#图像处理之图像目标质心检测的方法
下一篇: C#和JavaScript实现交互的方法