正则表达式
正则表达式(一) -- 元字符
正则表达式括号的作用 常用元字符 常用反义元字符
正则表达式之元字符一、最易理解的元字符。 脱字符 ^ :表示匹配行首的文本 美元符 $ :表示匹配行尾的文本 例如: ^cat //匹配以c作为一行的第一个字符是c,然后是一个a,紧接着一个t的文本 以上正则表达式匹配的是: 例如一个行 catdogcat 上面正则表达式匹配第一个cat。 特殊正则说明: ^cat$ //匹配行开头是cat,然后就是行末尾的cat,说白了就是一行中仅仅只包含cat的行,没有其他字符。 ^$ //匹配行开头,然后就是行末尾了,说白了就是匹配一个空行(没有任何字符,也没有空白字符) ^ //匹配行的开头,每一行都匹配 下面用C#说明: static void Main(string[] args) 二、字符组 匹配若干字符之一 [] //字符串用中括号括起来,表示匹配其中的任一字符,相当于或的意思 例如: gr[ea]y //匹配grey或gray 其中连字符 -表示一个范围,例如<h[1-6]>与 <h[123456]>的作用一致。其他类似的还有[a-z],[A-Z]。 这里必须要注意的是只有在字符组内部连字符 - 才是元字符,否则它就只匹配普通的连字符 - 。 static void Main(string[] args) { Regex reg = new Regex("<h[1-6]>"); string str = "<div><h1>你在他乡还好吗?</h1></div>"; Console.WriteLine(reg.Match(str)); //输出 <h1> Console.ReadKey(); } 三、排除型字符组 用[^...]取代[...]这个字符组就会匹配任何未列出的字符。 [^...] //[^...]表示匹配所有方括号里未列出的字符 例如: r[^abc]r //匹配出rar,rbr,rcr之外的任意r*r文本 下面的例子要注意下,例如正则表达式 q[^u] 不会匹配 Qantas 和 Iraq 这又是为什么呢? 因为正则表达式是区分大小写的。其次q[^u]要求q后面跟一个非u的字符,即必须包含一个字符。 static void Main(string[] args) { Regex reg = new Regex("a[^123456]"); Console.WriteLine(reg.Match("a1a2a3a4a5a6a7")); //输出 a7 Console.ReadKey(); } 在特别强调,排除型字符组表示“匹配一个未列出的字符”而不是“不要匹配列出的字符”。区别在于前者必须要匹配一个。 另外还要强调一点,在[]里面是没有元字符的,都代表本身的含义,例如[.]就表示匹配一个点.的意思。 四、点号.匹配任意字符 元字符.是用来匹配任意字符的字符组的渐变写法。 . //匹配任意字符的字符组简便写法 例如: .a //匹配 Aa 1a ga 等等 例子: static void Main(string[] args) { Regex reg = new Regex(".c"); Console.WriteLine(reg.Match("abcdefg")); //输出 bc Console.ReadKey(); } 五、多选结构 | 是一个非常简捷的元字符,它的意思是或。依靠它,我们能够把不同的子表达式组合成一个总的表达式,而这个总表达式又能够匹配任意的子表达式。 | //或 多选分支 选择两者中的一个 注意|将左右两边分为两部分,而不管左右两边有多长多乱 例如: gray|grey //既可匹配gray又可匹配grey 相当于gr[ae]y 如果将|写在中括号[]里面,那么 | 就不是元字符,它和a e一样,只代表本身字符。 对于表达式gr(a|e)来说,括号是必须的,如果没有括号,那么gra|ey的意思就成了 gra | ea 即匹配gry或匹配ey。 再比如 Frist|1st 与 (Fri|1)st 表示的是同一个意思 C#DEMO: static void Main(string[] args) { Regex reg = new Regex("abc|def"); Console.WriteLine(reg.Match("bcdefg")); //输出 def Console.ReadKey(); } 另外要特别注意下,下面的这个例子 ^from|subject|date: 与 ^(from|subject|date): 之间的区别 对于前者:只能匹配 ^from 或 subject 或 date: 对于后者: 能够匹配 ^from: 或 ^subject: 或 ^date: 六、忽略大小写 当然忽略大小写你可以用 [Aa]bc 取代 abc ,但是这样不方便。正则表达式提供一个 -i 。用于忽略大小写匹配。 -i //用于忽略大小写匹配 不过在C#中貌似不支持-i的写法,我测试过-i写在前面,但是无法匹配,要忽略大小写貌似要通过构造函数的属性设定: static void Main(string[] args) { Regex reg = new Regex("Abc",RegexOptions.IgnoreCase); Console.WriteLine(reg.Match("abcdefg")); //输出 abc Console.ReadKey(); } 七、单词分界符 b 表示单词分界符 b //匹配单词的开始或结束
代码示例: static void Main(string[] args) { Regex reg = new Regex(@"bLoveb"); Console.WriteLine(reg.Match("I Love You!")); //输出 Love Console.ReadKey(); } 八、可选项元素 ? 代表可选项,把他加在一个字符的后面,就表示此处容许出现这个字符,不过它的出现并非匹配成功的必要条件。 ? //跟在一个字符后面,容许此字符出现0次或1次 例如: colou?r //可以匹配colour或color C#Demo: static void Main(string[] args) { Regex reg = new Regex(@"colou?r"); Console.WriteLine(reg.Match("what is color?")); //输出 color Console.WriteLine(reg.Match("what is colour?")); //输出 colour Console.ReadKey(); } 然后来说一下结合其他元字符使用的情况: 例如: July|Jul 可缩短为 July? 4th|4 可缩短为 4(th)? 九、重复出现 加号+和星号*的作用与问号类似,的作用都是限定字符出现的次数。因此问号?加号+星号*这3个元字符统称量词。 ? //可以出现0次或1次 + //至少要出现1次,可以出现无数次 * //可以出现0次或出现无数次 Demo: static void Main(string[] args) { Regex reg = new Regex(@"colo*r"); Console.WriteLine(reg.Match("colooor")); //输出 colooor Regex reg2 = new Regex(@"colo*r"); Console.WriteLine(reg2.Match("colr")); //输出 colr Regex reg3 = new Regex(@"colo+r"); Console.WriteLine(reg3.Match("colr")); //输出 空白(啥都不输出,这就是+和*的区别了) Console.ReadKey(); } 十、规定重现次数的范围:区间 {min,max} 大括号内的数字用于表示某字符允许出现的次数区间。 {min,max} //大括号内的数字用于表示某字符允许出现的次数区间。 C# Demo: static void Main(string[] args) { Regex reg = new Regex(@"colo{3,5}r"); Console.WriteLine(reg.Match("colooor")); //输出 colooor Regex reg2 = new Regex(@"colo{3,5}r"); Console.WriteLine(reg2.Match("coloor")); //输出 空白(啥都不输出) 至少3个,但是字符串里只有两个,因此不符合 Console.ReadKey(); } 这里要记住,{}里面的参数不一定要写全两个,也可以仅仅写一个,这样代表仅仅匹配指定的字符数,例如b{6}b匹配刚刚6个字母的单词。 {n,} 匹配n次或更多次, {5,} 匹配5次以上 十一、括号以及反向引用 前面已经说过括号的两个作用:限制多选项的范围,将若干字符组合为一个单元,受问号或星号之类的量词作用。现在在来说一种括号的用法,分组,此东西具有记忆的功能,即在正则表达式内部仍然能够回忆上次匹配到的是什么。这个东西用语言说不明白,书本上又是画图又是线的,这里仅仅用一个例子: static void Main(string[] args) { Regex reg = new Regex(@"(b[A-Za-z]+ +)1b"); Console.WriteLine(reg.Match("red color color red")); //输出 color color Console.ReadKey(); } 例子解析:首先说明一下括号里面代表什么意思, (b[A-Za-z]+ +) 匹配单词的开始,然后是大小写字母至少1次,然后空格至少1次。说白了就是 空格然后是匹配不区分大小写的一寸字母然后是任意个空格
OK,再来说下1b b当然就是单词的结尾了,那么1呢?这个就是分组的作用了,1代表的就是前面括号里面的东西,也就是一个单词。
因此,整个正则表达式的意思是,匹配间隔了N个空格的重复的单词。不懂也没办法了。
十二、神奇的转义 转义符它的作用是使元字符失去它的意义,仅仅代表其日常输入中字符的意义。 C#例子: static void Main(string[] args) { Regex reg = new Regex(@".c"); Console.WriteLine(reg.Match("(acdefg")); //输出 ac Regex reg2 = new Regex(@".c"); Console.WriteLine(reg2.Match("(acdefg")); //输出 空白(啥都不输出,说明.已失去了它元字符,代表任意字符的意义) Regex reg3 = new Regex(@".c"); Console.WriteLine(reg3.Match("(.cdefg")); //输出 .c 它字表它自己,就匹配一个点.了 Console.ReadKey(); } 例如,我要匹配字符 . 字符* 就需要在前面加反斜杠,. *去除它元字符的含义。 一些需要转义的字符列表 * + ? | { [ ( ) ^ $ . # 和 空白 十三、一些其他的元字符 w 匹配字母,汉字,数字,下划线 W 匹配非字母,非汉字,非数字,非下划线 s 匹配空白符 S 匹配非空白符 d 匹配数字 D 匹配非数字 static void Main(string[] args) { Regex reg = new Regex(@"w?"); MatchCollection mcoll = reg.Matches("@你s_5"); foreach (Match mat in mcoll) { Console.WriteLine(mat.Value); //输出 空白 你 s _ 5 果然是匹配汉字、字母、下划线、数字 } Regex reg2 = new Regex(@"s"); MatchCollection mcoll2 = reg2.Matches("abc def"); foreach (Match mat in mcoll2) { Console.WriteLine(mat.Index); //输出 3 这里要注意一个问题了,在用Matches时,当匹配不到时,会返回Empty,因此,可以认为每次都是匹配到的,但是匹配到空 } Regex reg3 = new Regex(@"d"); //匹配数字 Match m2 = reg3.Match("abc5def"); Console.WriteLine(m2.Value); //输出 5 //以下代码为完全复制上面的代码,只是改了命名与正则 Regex reg4 = new Regex(@"W?"); MatchCollection mcoll3 = reg4.Matches("@你s_5"); foreach (Match mat in mcoll2) { Console.WriteLine(mat.Value); //输出 @ } Regex reg5 = new Regex(@"S"); //匹配非空格 MatchCollection mcoll4 = reg5.Matches("abc def"); foreach (Match mat in mcoll4) { Console.WriteLine(mat.Value); //输出 abcdef 这里要注意一个问题了,在用Matches时,当匹配不到时,会返回Empty,因此,可以认为每次都是匹配到的,但是匹配到空 } Regex reg6 = new Regex(@"D"); //匹配非数字 Match m3 = reg6.Match("abc5def"); Console.WriteLine(m3.Value); //输出 a Match就是只匹配第一个 Console.ReadKey(); } 还有,既然学习了正则表达式,就千万不要忘记这一个用法:
___________________________________________________________________________________________________________________________________- 转载出处http://www.cnblogs.com/kissdodog/archive/2013/04/22/3036649.html (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |