正则表达式 (一) 快速入门
1. 什么是正则表达式? 1.1正则表达式概念 正则表达式,又称正则表示法,英文名:RegularExpression(简写为regex、regexp或RE),是计算机科学的一个重要概念。他是用一种数学算法来解决计算机程序中的文本检索、区配等问题。 1.2正则表达式语言支持 正则表达式其实与语言无关,在很多语言中都提供了支持,包括最常用的脚本语言Javascript。当然C#语言也毫不例外的提供了很好的支持。
1.3正式表达式的应用 在进阶系列文章的开始就介绍正则表达式,是因为他非常常用,在我们开发应用程序的时候,需要对输入内容进行格式校验,需要对复杂的字符中找出规律检索出我们想要的部分。对于刚接触的人来说,比较晦涩难懂,当你读完本篇以后,就会感觉正则表达式并不是什么复杂的东西。 因此使用正则表达式,可以帮助我们解决以下问题: A.检索:可以通过正则表达式,从字符串中获取我们想要的特定部分。 B.匹配:给定的字符串是否符合正则表达式的过滤逻辑 下面几种应用场景,都特别适合正则表达式来解决 A.在论坛或博客中发贴时过滤敏感的字词 B.在应用软件中进行输入格式校验时 C.对一段复杂文本中进行有规则的替换时 D.将一段复杂文本按一定的规则变为另一种形式时 下面我们会介绍正则表达式的基础知识。 2. 正则表达式的组成 一个正则表达式就是由普通字符以及特殊字符(称为元字符)组成的文字模式。该模式描述在查找文字主体时待匹配的一个或多个字符串。正则表达式作为一个模板,将某个字符模式与所搜索的字符串进行匹配。 下面,我把特殊字符,也就是元字符列举一下
小伙伴们不要被上面的表格吓坏了,下面我会以C#中应用正则表达式为例一一说明的,上面的表格中的元字符在今后的应用中,可以作为查阅和参考。 3. C#中使用正则表达式 3.1C#中正则表达式的命名空间 System.Text.RegularExpressions命名空间包含一些类,这些类提供对.NETFramework正则表达式引擎的访问。该命名空间提供正则表达式功能,可以从运行在Microsoft.NETFramework内的任何平台或语言中使用该功能。除了此命名空间中包含的类型外,System.Configuration.RegexStringValidator类还允许您确定特定字符串是否与某个正则表达式模式相符。 总结一下,在.net中有两个命名空间用于操作正则表达式 A.System.Text.RegularExpressions命名空间下在的类、委托、枚举https://msdn.microsoft.com/zh-cn/library/system.text.regularexpressions.aspx B.System.Configuration.RegexStringValidator类 3.2常用的操作正则表达式的方法和委托 其中System.Text.RegularExpressions下的Regex类中提供了很多静态方法(比较常用的有IsMatch、Match、Matches、Replace、Split等)和委托MatchEvaluator. 3.2.1静态方法IsMatch IsMatch方法返回值为一个布尔型,主要用于判断指定的字符串是否与正则表达式字符串匹配,它有三个重载方法 bool IsMatch(string input,string pattern); 参数:input:要搜索匹配项的字符串。 pattern:要匹配的正则表达式模式。 bool IsMatch(string input,string pattern,RegexOptions options); 参数:input:要搜索匹配项的字符串。 pattern:要匹配的正则表达式模式。 options下面有详细说明 bool IsMatch(string input,RegexOptions options,TimeSpan matchTimeout); 参数:input:要搜索匹配项的字符串。 pattern:要匹配的正则表达式模式。 3.2.2关于参数RegexOptionsoptions 正则表达式选项RegexOptions有如下一下选项,详细说明请参考联机帮助
这里我提到内联标志,是因为相对于用RegexOptions在newRegex时定义Regex表达式的全局选项来说,内联标志可以更小粒度(以组为单位)的定义匹配选项,从而更方便表达我们的思想 语法是这样的:(?i:expression)为定义一个选项,(?-i:expression)为删除一个选项,(?i-s:expression)则定义i,删除s,是的,我们可以一次定义很多个选项。这样,通过内联选项,你就可以在一个Regex中定义一个组为匹分大小写的,一个组不匹分大小写的 3.2.3静态方法Match 静态方法Match,使用指定的匹配选项在输入字符串中搜索指定的正则表达式的第一个匹配项。返回一个包含有关匹配的信息的对象。同样有三个重载方法,参数和IsMatch方法相同。此外,在Regex类中,还有一个同名的非静态方法,适用于多个实例的情况下,效率更高一些。 Match Match(string input,string pattern); Match Match(string input,RegexOptions options); Match Match(string input,TimeSpan matchTimeout); 3.2.4静态方法Matches 静态方法Matches,在指定的输入字符串中搜索指定的正则表达式的所有匹配项。跟上面方法不同之处,就是这个方法返回的是所有匹配项,他同样有三个重载方法,并且参数和Match方法完全相同 Match Matches(string input,string pattern); Match Matches(string input,RegexOptions options); Match Matches(string input,TimeSpan matchTimeout); 3.2.5 Replace函数有四个重载函数 我们知道正则表达式主要是实现验证,提取,分割,替换字符的功能.Replace函数是实现替换功能的. 1)Replace(stringinput,stringpattern,stringreplacement) //input是源字符串,pattern是匹配的条件,replacement是替换的内容,就是把符合匹配条件pattern的内容转换成它 比如stringresult=Regex.Replace("abc","ab","##"); //结果是##c,就是把字符串abc中的ab替换成## 2)Replace(stringinput,stringreplacement,RegexOptionsoptions) //RegexOptions是一个枚举类型,用来做一些设定. //前面用注释时就用到了RegexOptions.IgnorePatternWhitespace.如果在匹配时忽略大小写就可以用RegexOptions.IgnoreCase 比如stringresult=Regex.Replace("ABc","##",RegexOptions.IgnoreCase); 如果是简单的替换用上面两个函数就可以实现了.但如果有些复杂的替换,比如匹配到很多内容,不同的内容要替换成不同的字符.就需要用到下面两个函数 3)Replace(stringinput,MatchEvaluatorevaluator); //evaluator是一个代理,其实简单的说是一个函数指针,把一个函数做为参数参进来 //由于C#里没有指针就用代理来实现类似的功能.你可以用代理绑定的函数来指定你要实现的复杂替换. 4)Replace(stringinput,MatchEvaluatorevaluator,RegexOptionsoptions); //这个函数上上面的功能一样,只不过多了一点枚举类型来指定是否忽略大小写等设置 3.2.6静态方法Split拆分文本 使用正则表达式匹配的位置,将文本拆分为一个字符串数组,同样有三个重载方法,返回值为字符串数组 string[] Split(string input,string pattern); string[] Match(string input,RegexOptions options); string[] Match(string input,TimeSpan matchTimeout); 下面我们会分别介绍最常用的正则表达式的使用 4. @符号 在“@”虽然并非C#正则表达式的“成员”,但是它经常与C#正则表达式出双入对。“@”表示,跟在它后面的字符串是个“逐字字符串”, 示例: string strFirst="C:Program FilesIIS"; string strSecond=@"C:Program FilesIIS"; Console.WriteLine(strFirst); Console.WriteLine(strSecond); 以上定义字符串是等价的。 5. 定位字符
表5定位元字符 示例一:区配开始^ string str = "I am Blue cat"; Console.WriteLine(Regex.Replace(str,"^","准备开始:")); 输出结果为: 示例二:区始结束$ string str = "I am Blue cat"; Console.WriteLine(Regex.Replace(str,"$"," 结束了!")); 输出结果为: 6. 字符转义 当我们要查询元字符时,比如查询*或.必须使用转义符,当然查询/必须使用 7. 基本语法元字符
表7基本语法元字符 示例一:校验只允许输入数字 string strCheckNum1 = "23423423a3",strCheckNum2 = "324234"; Console.WriteLine("匹配字符串"+strCheckNum1+"是否为数字:"+Regex.IsMatch(strCheckNum1,@"^d*$")); Console.WriteLine("匹配字符串" + strCheckNum2 + "是否为数字:" + Regex.IsMatch(strCheckNum2,@"^d*$")); 输出结果为: 其中*表示重复多次检查字符,后面重复字符中会具体说明 示例二:校验只允许输入除大小写字母、0-9的数字、下划线_以外的任何字 //示例二:校验只允许输入除大小写字母、0-9的数字、下划线_以外的任何字符 string strCheckStr1 = "abcds_a",strCheckStr2 = "**&&((((2",strCheckStr3 = "**&&(((("; string regexStr = @"^W*$"; Console.WriteLine("匹配字符串" + strCheckStr1 + "是否为除大小写字母、0-9的数字、下划线_以外的任何字符:" + Regex.IsMatch(strCheckStr1,regexStr)); Console.WriteLine("匹配字符串" + strCheckStr2 + "是否为除大小写字母、0-9的数字、下划线_以外的任何字符:" + Regex.IsMatch(strCheckStr2,regexStr)); Console.WriteLine("匹配字符串" + strCheckStr3 + "是否为除大小写字母、0-9的数字、下划线_以外的任何字符:" + Regex.IsMatch(strCheckStr3,regexStr)); 输出结果为: 8. 反义
表8 反义字符 上面的示例中已经使用到到反义了,我们举一个匹配除某些字母外的任意字符 示例:查找除ahou这之外的所有字符 //示例:查找除ahou这之外的所有字符 string strFind1 = "I am a Cat!",strFind2 = "My Name's Blue cat!"; Console.WriteLine("除ahou这之外的所有字符,原字符为:" + strFind1 + "替换后:" + Regex.Replace(strFind1,@"[^ahou]","*")); Console.WriteLine("除ahou这之外的所有字符,原字符为:" + strFind2 + "替换后:" + Regex.Replace(strFind2,"*")); 执行结果为: 9. 重复描述字符
表9重复描述字符 前面已经学习了*表示重复检索多个字符,下面我们具体应用一个实例 示例:校验输入内容是否为合法QQ号(备注:QQ号为5-12位数字) //示例:校验输入内容是否为合法QQ号(备注:QQ号为5 - 12位数字) string isQq1 = "1233",isQq2 = "a1233",isQq3 = "0123456789123",isQq4 = "556878544"; string regexQq = @"^d{5,12}$"; Console.WriteLine(isQq1+"是否为合法QQ号(5-12位数字):" + Regex.IsMatch(isQq1,regexQq)); Console.WriteLine(isQq2 + "是否为合法QQ号(5-12位数字):" + Regex.IsMatch(isQq2,regexQq)); Console.WriteLine(isQq3 + "是否为合法QQ号(5-12位数字):" + Regex.IsMatch(isQq3,regexQq)); Console.WriteLine(isQq4 + "是否为合法QQ号(5-12位数字):" + Regex.IsMatch(isQq4,regexQq)); 运行结果为: 10. 择一匹配
示例一:查找数字或字母 //示例:查找数字或字母 string findStr1 = "ad(d3)-df"; string regexFindStr = @"[a-z]|d"; string newStrFind=String.Empty; MatchCollection newStr = Regex.Matches(findStr1,regexFindStr); newStr.Cast<Match>().Select(m => m.Value).ToList<string>().ForEach(i => newStrFind += i); Console.WriteLine(findStr1 + "中的字母和数字组成的新字符串为:" + newStrFind); 输出结果为: 示例二:将人名输出("zhangsan;lisi,wangwu.zhaoliu") //示例:使用Split方法拆分 string strSplit = "zhangsan;lisi,wangwu.zhaoliu"; string regexSplitstr = @"[;]|[,]|[.]"; Regex.Split(strSplit,regexSplitstr).ToList().ForEach(i => Console.WriteLine(i)); 输出结果如下: 示例三:校验国内电话号码(支持三种写法校验 A. 010-87654321 B. (010)87654321 C.01087654321 D.010 87654321) //示例:校验国内电话号码(支持三种写法校验 A. 010-87654321 B. (010)87654321 C.01087654321 D.010 87654321) string TelNumber1 = "(010)87654321",TelNumber2 = "010-87654321",TelNumber3 = "01087654321",TelNumber4 = "09127654321",TelNumber5 = "010)87654321",TelNumber6="(010-87654321",TelNumber7="91287654321"; Regex RegexTelNumber1 =new Regex(@"(?0d{2,3}[-)]?d{7,8}"); Console.WriteLine( "电话号码 "+TelNumber1+" 是否合法:" + RegexTelNumber1.IsMatch(TelNumber1)); Console.WriteLine("电话号码 " + TelNumber2 + " 是否合法:" + RegexTelNumber1.IsMatch(TelNumber2)); Console.WriteLine("电话号码 " + TelNumber3 + " 是否合法:" + RegexTelNumber1.IsMatch(TelNumber3)); Console.WriteLine("电话号码 " + TelNumber4 + " 是否合法:" + RegexTelNumber1.IsMatch(TelNumber4)); Console.WriteLine("电话号码 " + TelNumber5 + " 是否合法:" + RegexTelNumber1.IsMatch(TelNumber5)); Console.WriteLine("电话号码 " + TelNumber6 + " 是否合法:" + RegexTelNumber1.IsMatch(TelNumber6)); Console.WriteLine("电话号码 " + TelNumber7 + " 是否合法:" + RegexTelNumber1.IsMatch(TelNumber7)); Console.WriteLine("n"); //上面未使用择一写法,导致TelNumber4和TelNumber5被合法化 //注意第二个分枝加了^ $符,表示从头到尾检索,不加的开始符,容易产生(010-87654321合法化(网上30分钟正则教程中,就存在此错误) //改进使用择一写法后如下: Console.WriteLine("n"); Regex RegexTelNumber3 = new Regex(@"(0d{2,3})[- ]?d{7,8}|^0d{2,3}[- ]?d{7,8}$"); Console.WriteLine("电话号码 " + TelNumber1 + " 是否合法:" + RegexTelNumber3.IsMatch(TelNumber1)); Console.WriteLine("电话号码 " + TelNumber2 + " 是否合法:" + RegexTelNumber3.IsMatch(TelNumber2)); Console.WriteLine("电话号码 " + TelNumber3 + " 是否合法:" + RegexTelNumber3.IsMatch(TelNumber3)); Console.WriteLine("电话号码 " + TelNumber4 + " 是否合法:" + RegexTelNumber3.IsMatch(TelNumber4)); Console.WriteLine("电话号码 " + TelNumber5 + " 是否合法:" + RegexTelNumber3.IsMatch(TelNumber5)); Console.WriteLine("电话号码 " + TelNumber6 + " 是否合法:" + RegexTelNumber3.IsMatch(TelNumber6)); Console.WriteLine("电话号码 " + TelNumber7 + " 是否合法:" + RegexTelNumber3.IsMatch(TelNumber7)); 运行结果如下:
11. 要点: A.本篇主要说明了正则表达式的基本元字符及使用方法举例 B.说明了C#中使用正则表达式的几种方法 这些只是最基础的正则表达式的内容,学习本节内容,我们还不能完成复杂的正则表达式, 在下一节中,我们会继续说明正则表达式更深层次的使用。 下面附本节所有示例代码: 1 //开始和结束符 ^ $ 2 string str = "I am Blue cat"; 3 Console.WriteLine(Regex.Replace(str,"准备开始:")); 4 string str2 = "I am Blue cat"; 5 Console.WriteLine(Regex.Replace(str2," 结束了!")); 6 7 string str3 = "myWord.*"; 8 Console.WriteLine(Regex.Replace(str3,".*",".doc")); 9 10 //示例:校验只允许输入数字 11 12 string strCheckNum1 = "23423423a3",strCheckNum2 = "324234"; 13 Console.WriteLine("匹配字符串"+strCheckNum1+"是否为数字:"+Regex.IsMatch(strCheckNum1,@"^d*$")); 14 Console.WriteLine("匹配字符串" + strCheckNum2 + "是否为数字:" + Regex.IsMatch(strCheckNum2,@"^d*$")); 15 16 //示例二:校验只允许输入除大小写字母、0-9的数字、下划线_以外的任何字符 17 string strCheckStr1 = "abcds_a",strCheckStr3 = "**&&(((("; 18 string regexStr = @"^W*$"; 19 Console.WriteLine("匹配字符串" + strCheckStr1 + "是否为除大小写字母、0-9的数字、下划线_以外的任何字符:" + Regex.IsMatch(strCheckStr1,regexStr)); 20 Console.WriteLine("匹配字符串" + strCheckStr2 + "是否为除大小写字母、0-9的数字、下划线_以外的任何字符:" + Regex.IsMatch(strCheckStr2,regexStr)); 21 Console.WriteLine("匹配字符串" + strCheckStr3 + "是否为除大小写字母、0-9的数字、下划线_以外的任何字符:" + Regex.IsMatch(strCheckStr3,regexStr)); 23 24 //示例:查找除ahou这之外的所有字符 25 string strFind1 = "I am a Cat!",strFind2 = "My Name's Blue cat!"; 26 Console.WriteLine("除ahou这之外的所有字符,原字符为:" + strFind1 + "替换后:" + Regex.Replace(strFind1,"*")); 27 Console.WriteLine("除ahou这之外的所有字符,原字符为:" + strFind2 + "替换后:" + Regex.Replace(strFind2,"*")); 28 29 //示例:校验输入内容是否为合法QQ号(备注:QQ号为5 - 12位数字) 30 string isQq1 = "1233",isQq4 = "556878544"; 31 string regexQq = @"^d{5,12}$"; 32 Console.WriteLine(isQq1+"是否为合法QQ号(5-12位数字):" + Regex.IsMatch(isQq1,regexQq)); 33 Console.WriteLine(isQq2 + "是否为合法QQ号(5-12位数字):" + Regex.IsMatch(isQq2,regexQq)); 34 Console.WriteLine(isQq3 + "是否为合法QQ号(5-12位数字):" + Regex.IsMatch(isQq3,regexQq)); 35 Console.WriteLine(isQq4 + "是否为合法QQ号(5-12位数字):" + Regex.IsMatch(isQq4,regexQq)); 37 38 //示例:查找数字或字母 39 string findStr1 = "ad(d3)-df"; 40 string regexFindStr = @"[a-z]|d"; 41 string newStrFind=String.Empty; 42 MatchCollection newStr = Regex.Matches(findStr1,regexFindStr); 43 newStr.Cast<Match>().Select(m => m.Value).ToList<string>().ForEach(i => newStrFind += i); 44 Console.WriteLine(findStr1 + "中的字母和数字组成的新字符串为:" + newStrFind); 45 46 //示例:使用Split方法拆分 47 string strSplit = "zhangsan;lisi,wangwu.zhaoliu"; 48 string regexSplitstr = @"[;]|[,]|[.]"; 49 Regex.Split(strSplit,regexSplitstr).ToList().ForEach(i => Console.WriteLine(i)); 52 53 //示例:校验国内电话号码(支持三种写法校验 A. 010-87654321 B. (010)87654321 C.01087654321 D.010 87654321) 54 string TelNumber1 = "(010)87654321",55 TelNumber4 = "09127654321",56 TelNumber7="91287654321"; 57 Regex RegexTelNumber1 =new Regex(@"(?0d{2,8}"); 58 Console.WriteLine( "电话号码 "+TelNumber1+" 是否合法:" + RegexTelNumber1.IsMatch(TelNumber1)); 59 Console.WriteLine("电话号码 " + TelNumber2 + " 是否合法:" + RegexTelNumber1.IsMatch(TelNumber2)); 60 Console.WriteLine("电话号码 " + TelNumber3 + " 是否合法:" + RegexTelNumber1.IsMatch(TelNumber3)); 61 Console.WriteLine("电话号码 " + TelNumber4 + " 是否合法:" + RegexTelNumber1.IsMatch(TelNumber4)); 62 Console.WriteLine("电话号码 " + TelNumber5 + " 是否合法:" + RegexTelNumber1.IsMatch(TelNumber5)); 63 Console.WriteLine("电话号码 " + TelNumber6 + " 是否合法:" + RegexTelNumber1.IsMatch(TelNumber6)); 64 Console.WriteLine("电话号码 " + TelNumber7 + " 是否合法:" + RegexTelNumber1.IsMatch(TelNumber7)); 65 66 Console.WriteLine("n"); 67 68 //上面未使用择一写法,导致TelNumber4和TelNumber5被合法化 69 //注意第二个分枝加了^ $符,表示从头到尾检索,不加的开始符,容易产生(010-87654321合法化(网上30分钟正则教程中,就存在此错误) 70 //改进使用择一写法后如下: 71 72 Console.WriteLine("n"); 73 74 Regex RegexTelNumber3 = new Regex(@"(0d{2,8}$"); 75 76 Console.WriteLine("电话号码 " + TelNumber1 + " 是否合法:" + RegexTelNumber3.IsMatch(TelNumber1)); 77 Console.WriteLine("电话号码 " + TelNumber2 + " 是否合法:" + RegexTelNumber3.IsMatch(TelNumber2)); 78 Console.WriteLine("电话号码 " + TelNumber3 + " 是否合法:" + RegexTelNumber3.IsMatch(TelNumber3)); 79 Console.WriteLine("电话号码 " + TelNumber4 + " 是否合法:" + RegexTelNumber3.IsMatch(TelNumber4)); 80 Console.WriteLine("电话号码 " + TelNumber5 + " 是否合法:" + RegexTelNumber3.IsMatch(TelNumber5)); 81 Console.WriteLine("电话号码 " + TelNumber6 + " 是否合法:" + RegexTelNumber3.IsMatch(TelNumber6)); 82 Console.WriteLine("电话号码 " + TelNumber7 + " 是否合法:" + RegexTelNumber3.IsMatch(TelNumber7)); 转自:http://www.cnblogs.com/yubinfeng/p/4606605.html (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- 使用waitpid还是sigaction?
- 在Swift使用Objective-C时,Xcode不识别CGFloat / UIFont /
- c# – FluentAssertions无法识别异步方法/ Func的ShouldNot
- 用JSONObject和JSONArray 解析json数据
- 语法参考系列——(一)如何读懂Swift的语言参考
- 【Flex】Flex socket (1)
- An Example SQLite based iOS 4 iPhone Application (Xcode
- Optane P4800X评测(2):Oracle 170万TPM意味着什么?
- 发布来自vb.net的推文
- 在oracle中的plsql – PLS-00323错误