zoukankan      html  css  js  c++  java
  • 正则表达式(一) 元字符

    正则表达式括号的作用
    1、限制多选项的范围 (Fri|1)st 这样写会匹配Frist或1st 如果去掉,则 Fri|1st就是匹配 Fri或1st
    2、将若干个字符进行组合,受量词的同时作用。例如 th+ 表示匹配 th thh thhh(h无数次),如果是(th)+,则匹配的是th thth ththth(th无数次)
    3、反向引用,即前面括号匹配到的东西记忆与后面,常用于匹配重复单词。
    4、分组

    常用元字符
    代码           说明
    .             匹配除换行符以外的任意字符
    \w             匹配字母或数字或下划线或汉字
    \s             匹配任意的空白符
    \d             匹配数字
    \b             匹配单词的开始或结束
    ^             匹配行的开始
    $             匹配行的结束

    常用反义元字符
    代码   说明
    \W       匹配任意不是字母,数字,下划线,汉字的字符
    \S        匹配任意不是空白符的字符
    \D      匹配任意非数字的字符
    \B        匹配不是单词开头或结束的位置
    [^x]       匹配除了x以外的任意字符
    [^aeiou]   匹配除了aeiou这几个字母以外的任意字符


    常用重复限定符
    代码       说明
    *         重复零次或更多次
    +         重复一次或更多次
    ?         重复零次或一次
    {n}       重复n次
    {n,}        重复n次或更多次
    {n,m}       重复n到m次

    正则表达式之元字符

     一、最易理解的元字符。

      脱字符  ^   :表示匹配行首的文本

        美元符  $ :表示匹配行尾的文本

      例如:

    ^cat    //匹配以c作为一行的第一个字符是c,然后是一个a,紧接着一个t的文本

      以上正则表达式匹配的是:

      例如一个行  catdogcat  上面正则表达式匹配第一个cat。

      特殊正则说明:

    ^cat$    //匹配行开头是cat,然后就是行末尾的cat,说白了就是一行中仅仅只包含cat的行,没有其他字符。
    
    ^$        //匹配行开头,然后就是行末尾了,说白了就是匹配一个空行(没有任何字符,也没有空白字符)
    
    ^          //匹配行的开头,每一行都匹配

      下面用C#说明:

            static void Main(string[] args)
            {
                Regex reg = new Regex("^cat");
                reg.Match("catdog");
                Console.WriteLine(reg.Match("catdog"));     //输出 cat
                Console.WriteLine(reg.Match("dogcat"));     //输出 空白(啥都不输出)
    
                Regex reg2 = new Regex("cat$");
                Console.WriteLine(reg2.Match("catdog"));      //输出 空白(啥都不输出)
                Console.WriteLine(reg2.Match("dogcat"));      //输出 cat
    
                Console.ReadKey();
            }

    二、字符组

      匹配若干字符之一

    []    //字符串用中括号括起来,表示匹配其中的任一字符,相当于或的意思

      例如:

    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 后来发现是错的,应该是?i  (?i)放在前面就可以了

      (?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(@"\bLove\b");
                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]+ +)\1\b");
                Console.WriteLine(reg.Match("red color color red"));    //输出 color color
    
                Console.ReadKey();
            }

      例子解析:首先说明一下括号里面代表什么意思,

      (\b[A-Za-z]+ +)  匹配单词的开始,然后是大小写字母至少1次,然后空格至少1次。说白了就是 空格然后是匹配不区分大小写的一寸字母然后是任意个空格
      
      OK,再来说下\1\b  \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();
            }  

      还有,既然学习了正则表达式,就千万不要忘记这一个用法:

      

      

  • 相关阅读:
    第三百四十九、五十天 how can I 坚持
    第三百四十八天 how can I 坚持
    第三百四十七天 how can I 坚持
    第三百四十六天 how can I 坚持
    第三百四十五天 how can I 坚持
    第三百四十四天 how can I 坚持
    第三百四十三天 how can I 坚持
    第三百四十二天 how can I 坚持
    第三百四十一天 how can I 坚持
    POJ 2996:Help Me with the Game
  • 原文地址:https://www.cnblogs.com/kissdodog/p/3036649.html
Copyright © 2011-2022 走看看