C#正则学习
正则的力量无法小觑,短短的几个字符,往往胜过几十行的代码,大大可以简化我们冗余的代码。
以前在js里用正则比较多,今天来熟悉下C#中正则的使用方法,权当笔记了!
如果把正则当做一门语言的话,那么正则的学习也和其他语言一样,从历史渊源到基本语法,从高级特性到性能优化,正则一样不少。
历史:
正则表达式的“祖先”可以一直上溯至对人类神经系统如何工作的早期研究。Warren McCulloch 和 Walter Pitts 这两位神经生理学家研究出一种数学方式来描述这些神经网络。 1956 年, 一位叫 Stephen Kleene 的数学家在 McCulloch 和 Pitts 早期工作的基础上,发表了一篇标题为“神经网事件的表示法”的论文,引入了正则表达式的概念。正则表达式就是用来描述他称为“正则集的代数”的表达式,因此采用“正则表达式”这个术语。 随后,发现可以将这一工作应用于使用 Ken Thompson 的计算搜索算法的一些早期研究,Ken Thompson 是 Unix 的主要发明人。正则表达式的第一个实用应用程序就是 Unix 中的 qed 编辑器。 如他们所说,剩下的就是众所周知的历史了。从那时起直至现在正则表达式都是基于文本的编辑器和搜索工具中的一个重要部分。
基本语法字符:
\d (代表0-9的数字)
\D (代表除数字以外的其他字符)
\w (代表所有的单词字符-数字、字母、下划线)
\W (代表所有除单词字符外的字符)
\s (代表空白字符)
\S (代表除了空白字符以外的字符)
. (除了换行符外的任意字符)
[,,,] (匹配方括号内列出的所有字符)
[^,,,] (匹配方括号内列出的字符外的所有字符)
\b (匹配单词边界)
\B (匹配非单词边界)
^ (匹配字符开头位置)
$ (匹配字符结尾位置)
{n} (匹配n个符合条件的字符)
{n,m} (匹配n到m个符合条件的字符)
{n,} (匹配大于等于n个符合条件的字符)
? (匹配1次或0次符合条件的字符)
+ (匹配一次或多次符合条件的字符)
* (匹配0次或多次符合条件的字符)
(a|b) (匹配符合a条件或者b条件的字符)
下面练习一些基本的例子来熟悉上面的基本语法
1.匹配3个数字,例如134
\d{3}
2.匹配一个单词以字母开头字母结尾中间是一个或多个数字,例如a123b
^[a-zA-Z]\d+[a-zA-Z]$
3.匹配固定电话 例如 021-81234563 或者 0512-81755456
^\d{3,4}-\d{8}
4.匹配正整数
[1-9][0-9]*
5.匹配两位小数
(([0-9][1-9]*)|([1-9][0-9]*))+\.\d{2}
6.匹配邮政编码
^\d{6}$
7.匹配手机号码
^[1][3-9]\d{9}$
8.匹配身份证号码
^\d{18}$)|^\d{15}$
9.匹配汉字
^[\u4e00-\u9fa5]{1,}$
10.匹配URL
^http(s)?([\w-]+\.)+(\w-)+(/[\w-./?%&=]*)?$
上述是基本的使用语法,让我们来看看C#中是如何使用它们的
System.Text.RegularExpressions.Regex 这个事C#正则的使用类
他提供了如下方法来使用正则
1.IsMatch 是否匹配-示例代码:
//验证手机号码
public bool IsMobile(string mobile) {
return System.Text.RegularExpressions.Regex.IsMatch(mobile, @"^[1][3-9]\d{9}$");
}
2.Split 根据条件切割字符串
示例代码
//根据数字拆分字符串
public String[] SplitStr(String str) {
return System.Text.RegularExpressions.Regex.Split(str, @"[0-9]");
} protected void btn_split_Click(object sender, EventArgs e) {
string[] Result = SplitStr(this.tb_pwd.Text);
int Len = Result.Length;
for (int i = ; i < Len; i++) {
if (Result[i] != "") {
Response.Write("<script>alert('拆分为!" + Result[i] + "')</script>");
}
}
}
3.Replace
替换字符串
//替换字符串中的所有数字为指定字符
public String ReplaceWord(string str1, string str2) {
return System.Text.RegularExpressions.Regex.Replace(str1, @"\d", str2);
}
4.Matches
获取匹配集合
//验证重复出现的词(正则需要优化)
public String[] RepeatWords(string str) {
System.Text.RegularExpressions.MatchCollection matches =
System.Text.RegularExpressions.Regex.Matches(str, @"\b(?<word>\w+)\s+(\k<word>)\b", System.Text.RegularExpressions.RegexOptions.Compiled | System.Text.RegularExpressions.RegexOptions.IgnoreCase);
int AIndex = matches.Count;
if (AIndex != ) {
String[] RepeatWord = new string[AIndex];
int i=;
foreach (System.Text.RegularExpressions.Match match in matches) {
string word = match.Groups["word"].Value;
RepeatWord[i] = word;
i++;
}
return RepeatWord;
}
else {
return null;
}
}
正则的高级特性
1.分组和非捕获性分组
组是把符合括弧中组条件的字符保存起来,通过索引的方法供下面的匹配的调用
例如 需要匹配 abc123abc
我们可以这样^(abc)123\1$,这里的()即是一个需要捕获的组,他的条件是abc,这个时候在下一个位置,我们只要通过\1就可以重复利用上一次捕获过的值来匹配,如果有两个分组,那我们获取第二个分组就用\2
那在C#中如何利用呢?
string x = "abc123abc";
Regex r = new Regex(@"^(abc)123\1$");
if (r.IsMatch(x))
{
Console.WriteLine("group1 value:" + r.Match(x).Groups[].Value);//输出:abc
}
这里为何是Groups[1]呢 因为在匹配的时候第一个匹配的是符合所有条件的字符串,然后存储符合条件的组
我们也可以为组命名:
string x = "abc123abc";
Regex r = new Regex(@"^(?<test>abc)123\1$");
if (r.IsMatch(x))
{
Console.WriteLine("group1 value:" + r.Match(x).Groups["test"].Value);//输出:abc
}
这样是不是就更加形象了呢
有的时候我们想匹配组但是不想保存这个组匹配的内容,这个时候我们可以使用?:
string x = "abc123abc";
Regex r = new Regex(@"^(?:abc)123\1$");
if (r.IsMatch(x))
{
Console.WriteLine("group1 value:" + r.Match(x).Groups[].Value);//输出:null
}
2.贪婪模式和非贪婪模式
一般情况下,正则都是贪婪模式,尤其是在+或者*修饰的条件下,正则都会去尽可能的匹配更多的内容,但是如果添加了?号,这个时候立马就会变成非贪婪模式
string x = "Live for nothing,die for something";
Regex r1 = new Regex(@".*thing");
if (r1.IsMatch(x))
{
Console.WriteLine("match:" + r1.Match(x).Value);//输出:Live for nothing,die for something
}
Regex r2 = new Regex(@".*?thing");
if (r2.IsMatch(x))
{
Console.WriteLine("match:" + r2.Match(x).Value);//输出:Live for nothing
}
3.回溯与非回溯
在默认情况下正则匹配贪婪模式下,当匹配的字符陷入死胡同的时候,会进行回溯直到下一个字符能够接着匹配
比如 (.*)abc 来匹配123abc123abc 首先.*会进行贪婪匹配直到匹配到字符结尾的位置,接着匹配a,发现没有字符可以匹配上,引擎就向后回溯,直到a匹配到最后abc中的a,然后紧接着匹配b,然后匹配c 所以结果是 123abc123abc
好,接着来说明下非回溯模式的执行过程,同样首先.*像一只饿狼般的匹配到字符的结尾位置,这个时候开始匹配a 发现已经无法匹配,此模式下,不进行回溯,于是匹配失败,在有的业务下我们需要这样的非回溯匹配 ,语法例:(?>.*)abc
4.正向预搜索反向预搜索
不好解释,举例说明
正向预搜索
string x = "1024 used 2048 free";
Regex r1 = new Regex(@"\d{4}(?= used)");
if (r1.Matches(x).Count==)
{
Console.WriteLine("r1 match:" + r1.Match(x).Value);//输出:1024
}
Regex r2 = new Regex(@"\d{4}(?! used)");
if (r2.Matches(x).Count==)
{
Console.WriteLine("r2 match:" + r2.Match(x).Value); //输出:2048
}
r1表示匹配后面紧跟着used的四个数字 于是乎匹配了1024 r2 匹配后面不是紧跟着used的四个数字 于是乎 匹配2048
反向预搜索
string x = "used:1024 free:2048";
Regex r1 = new Regex(@"(?<=used:)\d{4}");
if (r1.Matches(x).Count==)
{
Console.WriteLine("r1 match:" + r1.Match(x).Value);//输出:1024
}
Regex r2 = new Regex(@"(?<!used:)\d{4}");
if (r2.Matches(x).Count==)
{
Console.WriteLine("r2 match:" + r2.Match(x).Value);//输出:2048
}
r1匹配前面紧着着used:的四个数字 于是乎匹配1024 r2匹配前面不是紧跟着used:的四个数字 于是乎撇配2048
看着例子理解就很好理解了,另外正向和反向的组是不保存的
C#正则学习的更多相关文章
- js 正则学习小记之匹配字符串
原文:js 正则学习小记之匹配字符串 今天看了第5章几个例子,有点收获,记录下来当作回顾也当作分享. 关于匹配字符串问题,有很多种类型,今天讨论 js 代码里的字符串匹配.(因为我想学完之后写个语法高 ...
- js 正则学习小记之左最长规则
原文:js 正则学习小记之左最长规则 昨天我在判断正则引擎用到的方法是用 /nfa|nfa not/ 去匹配 "nfa not",得到的结果是 'nfa'.其实我们的本意是想得到整 ...
- js 正则学习小记之NFA引擎
原文:js 正则学习小记之NFA引擎 之前一直认为自己正则还不错,在看 次碳酸钴,Barret Lee 等大神都把正则玩的出神入化后发现我只是个战五渣. 求抱大腿,求大神调教. 之前大致有个印象,正 ...
- js 正则学习小记之匹配字符串优化篇
原文:js 正则学习小记之匹配字符串优化篇 昨天在<js 正则学习小记之匹配字符串>谈到 个字符,除了第一个 个,只有 个转义( 个字符),所以 次,只有 次成功.这 次匹配失败,需要回溯 ...
- js 正则学习小记之匹配字符串字面量优化篇
昨天在<js 正则学习小记之匹配字符串字面量>谈到 个字符,除了第一个 个,只有 个转义( 个字符),所以 次,只有 次成功.这 次匹配失败,需要回溯后用 [^"] 才能匹配成功 ...
- php 正则学习取反符号~
php 正则学习取反符号~ ~(<a .*?>.*?</a>|<.*?>)~i 先看正则图形,有点偏差,但可以初步看出结果. 关于 ~ 是取反符号,看下面说明.
- java 正则学习
前言 在网上找了许多关于正则解析 URL,结果不是很满意,所以自己学习正则: java url 那么解析 url 的代码如下: import java.util.regex.Matcher; impo ...
- JavaScript(E5,6) 正则学习总结学习,可看可不看!
1.概述 正则表达式(实例)是一种表达文本模式(即字符串结构)的方法. 创建方式有两种方式: 一种是使用字面量,以斜杠表示开始和结束. var regex = /xyz/ 另一种是使用RegExp构造 ...
- js正则学习及一些正则集合
正则中文版详细说明请看中文版w3cschool-----http://www.w3school.com.cn/jsref/jsref_obj_regexp.asp微软正则表达式语言-快速参考:http ...
随机推荐
- hdu 3081 hdu 3277 hdu 3416 Marriage Match II III IV //灵活运用最大流量
3081 意甲冠军: n女生选择不吵架,他甚至男孩边(他的朋友也算.并为您收集过程).2二分图,一些副作用,有几个追求完美搭配(每场比赛没有重复的每一个点的比赛) 后.每次增广一单位,(一次完美匹配) ...
- android:GLSurfaceView绘制bitmap图片及glViewport调整的效果
首先看一下GLSurfaceView是怎样绘制的.正如android开发文档中描写叙述的那样,我们须要new一个GLSurfaceView对象,然后设置一个实现了Renderer接口的对象,我们须要写 ...
- IOS获得各种文档文件夹路径的方法
iphone沙箱模型的有四个目录,各自是什么,永久数据存储一般放在什么位置.得到模拟器的路径的简单方式是什么. documents,tmp.app,Library. (NSHomeDirectory( ...
- Android使用代码消除App数据并重新启动设备
/** * 使用代码消除App数据 * 我们不寻常的清除App数据,中找到相应的App * 然后选择其清除数据.以下给出代码实现. * * 注意事项: * 1 设备须要root * 2 该演示样例中删 ...
- ANDROID嵌入式应用Unity3D视图(画廊3D模型)
转载请注明来自大型玉米的博客文章(http://blog.csdn.net/a396901990),谢谢支持! 效果展示: watermark/2/text/aHR0cDovL2Jsb2cuY3N ...
- JPA实体继承映射
注意:据说,在本文所指的实体是@Entity注解的类. JPA在对象 - 关系映射通常情况下一个实体对应表,不管是什么这两个实体之间的关系.假设两个实体之间的继承关系.那么它是如何映射? JPA实体支 ...
- Intelli idea 常用快捷键汇总
To navigate to the implementation(s) of an abstract method, position the caret at its usage or its n ...
- 错误 4 自定义工具错误: 无法生成服务引用“DepartMentService”的代码。请检查其他错
原文:错误 4 自定义工具错误: 无法生成服务引用"DepartMentService"的代码.请检查其他错 问题: 错误 4 自定义工具错误: 无法生成服务引用" ...
- H264 编解码器架构简单
看完后H264/AVC 编解码器演示,头脑是刚刚离开以下三个: 1.H264并且不明白如何指定的编解码器来实现,仅定义了一个编码视频位流的语法.和比特流进行解码,这与MPEG 类似. 2.H264而一 ...
- Openstack本学习笔记——Neutron-server服务加载和启动源代码分析(三)
本文是在学习Openstack过程中整理和总结.因为时间和个人能力有限.错误之处在所难免,欢迎指正! 在Neutron-server服务载入与启动源代码分析(二)中搞定模块功能的扩展和载入.我们就回到 ...