zoukankan      html  css  js  c++  java
  • 正则积累

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Text.RegularExpressions;

    namespace 正则积累
    {
        class Program
        {
            static void Main(string[] args)
            {
                //Fun1();
                //Fun2();
                //Fun3();
                //Fun4();
                //Fun5();
                //Fun6();
                //Fun7();
                Fun8();
                //Regex reg = new Regex("^a.*b$");
                //string str = "aHello\nb";
                //Console.WriteLine(reg.Match(str).Value);
            }

            /// <summary>
            /// 分组引用
            /// </summary>
            static void Fun1()
            {
                string str = "'Hello'";
                string str2 = "'Hello\"";

                //在正则表达式中,\整数表示引用 第整数个括号内里文本
                //此正则表达式最后的 \1 表示引用此正则表达式第一个括号内的文本(即单引号或者双引号),此正则匹配 Hello 两边的引号一致字符串
                Regex reg = new Regex("(['\"])[a-zA-Z]*\\1");

                //匹配成功,因为Hello前面和后面都是单引号
                Match m = reg.Match(str);
                //m.Groups[0].Value其实就是m.Value
                Console.WriteLine(m.Groups[0].Value);
                //m.Groups[1].Value就是正则里第一个括号里的文本 , 既 '
                Console.WriteLine(m.Groups[1].Value);

                Console.WriteLine(reg.IsMatch(str2));

                //使用正则的Replace方法的时候,$整数表示引用 第整数个括号内里文本
                Console.WriteLine(reg.Replace("123'Hello'456", "$1"));//替换结果为"123'456"

                //以上两种引用括号内文本的方法,括号都是以左括号从左边开始计数的


                //使用括号分组,但是不算如引用计数的方法:在左括号后面加 ?:
                //reg2里面的\1应该是引用123,但是包含123的括号为(?:),所以此括号不参与引用计数,所以匹配成功
                Regex reg2 = new Regex("(?:123)*(['\"])[a-zA-Z]*\\1");
                Match m2 = reg2.Match(str);
                Console.WriteLine(reg2.IsMatch(str));
                Console.WriteLine(m2.Groups[0].Value);
                Console.WriteLine(m2.Groups.Count);//因为(?:123)不参与引用计数,所以m2.Groups.Count为 2
            }

            /// <summary>
            /// 匹配制定的位置
            /// </summary>
            static void Fun2()
            {
                Regex reg = new Regex("\\babc\\b");
                string str1 = "I am abc";
                string str2 = "I amabc";
                Console.WriteLine(reg.IsMatch(str1));
                Console.WriteLine(reg.IsMatch(str2));

                //下面这个例子在JS中无效
                Regex reg2 = new Regex("\\b你好\\b");
                string str3 = "中国 你好 黑";
                string str4 = "中国你好黑";
                Console.WriteLine(reg2.IsMatch(str3));
                Console.WriteLine(reg2.IsMatch(str4));
            }

            /// <summary>
            /// 正前向声明和反前向声明
            /// </summary>
            static void Fun3()
            {
                //正前向匹配,在[jJ]ava后者[jJ]ava[sS]cript后面一定要跟着冒号,但是匹配的值不包括冒号
                Regex reg = new Regex("[Jj]ava([Ss]cript)?(?=\\:)");
                string str = "Javascript: Good";
                Console.Write(reg.IsMatch(str) + "\t");
                Console.WriteLine(reg.Match(str).Value);//匹配的值为Javascript(没有包含冒号)

                Console.WriteLine(reg.IsMatch("Javascript : Good") + "\t");//不匹配,因为t和冒号之间还有一个空格           

                Console.Write(reg.IsMatch("Java:Good") + "\t");//匹配
                Console.WriteLine(reg.Match("Java:Good").Value);

                Console.WriteLine(reg.IsMatch("Java : Good") + "\t");//不匹配,因为a和冒号之间还有一个空格



                //反前向声明,在java后面跟任意字符,但是不能是script,且不区分大小写
                Regex reg2 = new Regex("Java(?!Script)(.*)", RegexOptions.IgnoreCase);
                Console.WriteLine(reg2.IsMatch("javascrip") + "\t" + reg2.Match("javascrip").Value);
                Console.WriteLine(reg2.IsMatch("Javascript is good") + "\t" + reg2.Match("Javascript").Value);

                Console.WriteLine(reg2.IsMatch("Java Script is good") + "\t" + reg2.Match("Java script is good").Value);

                //能在反前向声明中引用括号么
                Regex reg3 = new Regex("(['\"])hello[^\\1]");//本来想匹配的是 'hello再跟一个非'  或者 "hello再跟一个非" ,那么就与strEnd不匹配了 ,但是在字符类中使用括号引用是不合法的,所以居然还是匹配的
                string strEnd = "'hello'";
                string strEnd2 = "'hello\"";
                Console.WriteLine(reg3.IsMatch(strEnd));
                //那么我们在反前向声明中能使用括号引用么,看下面的代码
                Regex regEnd = new Regex("(['\"])hello(?!\\1)");
                Console.WriteLine(regEnd.IsMatch(strEnd));//匹配失败,说明在反前向声明中能使用括号引用
                Console.WriteLine(regEnd.IsMatch(strEnd2) + "\t" + regEnd.Match(strEnd2).Value);//匹配成功,但没有将 'hello后面的"也匹配出来
                Regex regEnd2 = new Regex("(['\"])hello(?!\\1).+");
                Console.WriteLine(regEnd2.IsMatch(strEnd2) + "\t" + regEnd2.Match(strEnd2).Value);//匹配成功,将 'hello后面的"也匹配出来
            }

            /// <summary>
            /// 回溯与非回溯
            /// </summary>
            static void Fun4()
            {
                #region 第一个例子
                string str = "www.csdn.net";
                Regex reg1 = new Regex(@"\w+\.(.*)\.\w+");
                Console.WriteLine(reg1.IsMatch(str));//匹配成功

                Regex reg2 = new Regex(@"\w+\.(?>.*)\.\w+");
                Console.WriteLine(reg2.IsMatch(str));//匹配失败

                /*
                    "www.csdn.net" 可以通过@"\w+\.(.*)\.\w+"来匹配,却不能通过@"\w+\.(?>.*)\.\w+"来匹配!为什么呢?

    原因是正则匹配是贪婪的,匹配时它会尽可能多的匹配最多的结果,所以,上例两个正则式中的.*都会把csdn.net匹配完, 这个时候,第一个表达式在开始匹配时发现\.\w+没得字符给它匹配了,所以它会进行回溯,所谓回溯,就是把.*匹配的结果往回推,回推留出来的字符再用来匹配\.\w+,直到\.\w+匹配成功,整个表达式返回成功的匹配结果。而第二个表达式,因使用的是非回溯匹配,所以,.*匹配完后,不允许通过回溯来匹配\.\w+,所以整个表达式匹配失败。

    请注意,回溯匹配是很浪费资源的一种匹配方式,所以,请尽量避免您的正则式要通过回溯来成功匹配,如上例,可以换成@"\w+\.([^\.]+\.)+
                 */
                #endregion

                #region 第二个例子
                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,  
                }

                Regex r2 = new Regex(@"(?>.*)thing,");
                if (r2.IsMatch(x))//不匹配  
                {
                    Console.WriteLine("match:" + r2.Match(x).Value);
                }
                else
                {
                    Console.WriteLine("不匹配");
                }
                //在r1中,“.*”由于其贪婪特性,将一直匹配到字符串的最后,  
                //随后匹配“thing”,但在匹配“,”时失败,  
                //此时引擎将回溯,并在“thing,”处匹配成功。  
                //在r2中,由于强制非回溯,所以整个表达式匹配失败。
                #endregion
            }

            /// <summary>
            /// 不包含某个字串的两种方法
            /// </summary>
            static void Fun5()
            {
                #region 第一种
                string str = "Java script is good";
                string strP1 = "<p>Helo World</p>";
                string strP2 = "<p>你好<div>Realy</div></p>";
                //匹配一个字符串,这个字符串为以“java”开头,但是不能有“script”这个子串,使用这种方法有两点需要注意:
                //1.*必须放在大括号外面即不能写成((?!script).*),如果放在里面,则正则会将“ script”与“script”对比不相等也就匹配了(因为正是式贪婪的)
                //2.正则表达式的结尾有没有$会造成两种结果:(1)如果有$,那么凡是这个字符串中包括“script”这个子串,就找不到匹配的结果;(2)如果没有$,那么正则就会寻找遇到"script"之前后者之后有没有匹配,如果str为“Java script is good”(既在此例子中)会匹配“java ”,如果str为“script javasdf”则会匹配到“javasdf”
                Regex regMost = new Regex("java((?!script).)*$", RegexOptions.IgnoreCase);
                Match m = regMost.Match(str);
                Console.WriteLine(regMost.IsMatch(str));

                //那么如果我们想匹配一个字符串,而这个字符串中不能包含某一个子串,还想获得匹配的子串,例如我们想获取一个<p>标签里面的内容,而这个<p>标签里不能包含<div>标签

                //在((?!<div>).)* 外再加一个括号,就可以获取匹配的文本了
                Regex regP = new Regex("<p>(((?!<div>).)*)</p>");

                Match mp = regP.Match(strP1);
                //匹配成功
                if (mp.Success)
                {
                    Console.WriteLine(mp.Groups[1].Value);
                }

                //匹配失败
                if (regP.IsMatch(strP2))
                {
                }
                else
                {
                    Console.WriteLine("不匹配" + strP2);
                }
                #endregion

                #region 第二种
                //string myStr = "Java script is good";
                ////匹配一个以“java”开头的字符串,并且这个匹配的字符串中不能包含“script”
                //Regex myReg = new Regex("Java(?!.*script.*)", RegexOptions.IgnoreCase);
                //Match m2 = myReg.Match(myStr);
                //Console.WriteLine(m2.Success);

                ////Regex regL = new Regex("(<p>((?!<\\/p>).)*<\\/p>)|(<br\\/>)");

                Regex myReg2 = new Regex("<p>(?!.*<div>.*)(.*)</p>");
                Match myRes = myReg2.Match(strP1);
                if (myRes.Success)
                {
                    Console.WriteLine(myRes.Groups[1].Value);
                }
                if (myReg2.IsMatch(strP2))
                {
                }
                else
                {
                    Console.WriteLine("不匹配" + strP2);
                }
                #endregion
            }

            /// <summary>
            /// 永远不会匹配的正则
            /// </summary>
            static void Fun6()
            {
                Regex reg = new Regex("q(?=u)i");
                string s = "quit";
                //不匹配,因为正前向声明实际不消耗字符
                //Console.WriteLine(reg.IsMatch(s));

                //下面的正则能匹配,因为\d消耗了4
                Regex reg2 = new Regex("123(?=4)\\dabc");
                Console.WriteLine(reg2.IsMatch("1234abc"));
            }

            /// <summary>
            /// 向后查看
            /// </summary>
            static void Fun7()
            {
                string str = "abc123mm";
                //肯定式向后查看
                Regex reg = new Regex("(?<=123)mm");
                Console.WriteLine(reg.IsMatch(str));//匹配成功
                if (reg.IsMatch(str))
                {
                    Console.WriteLine(reg.Match(str).Value);
                }
                Console.WriteLine(reg.IsMatch("23mm"));//匹配失败
                Console.WriteLine("--------------------------------------------------------");
                //否定式向后查看
                Regex reg2 = new Regex("(?<!123)mm");
                Console.WriteLine(reg2.IsMatch("abc123mm"));//匹配失败
                Console.WriteLine(reg2.IsMatch("abcmm"));//匹配成功
                Console.WriteLine(reg2.Match("abcmm").Value);
            }

            /// <summary>
            /// 单行模式和多行模式
            /// </summary>
            static void Fun8()
            {
                //1.默认既不是单行模式也不是多行模式            
                Console.WriteLine(Regex.IsMatch("a\nb", "a.{1}b"));// .不能匹配换行符
                //下面两个例子说明,既不是单行模式也不是多行模式的时候,^只能匹配字符串开头,$能匹配字符串结尾和行的结尾
                Console.WriteLine(Regex.IsMatch("a\nb", "^a\\nb$"));//^匹配字符串开头,$匹配字符串结尾
                Console.WriteLine(Regex.IsMatch("\nab", "^ab"));//^不能匹配行开头
                Console.WriteLine(Regex.IsMatch("ab\n", "ab$"));//$能匹配行结尾

                //单行模式
                Console.WriteLine(Regex.IsMatch("a\nb", "a.{1}b", RegexOptions.Singleline));// .能匹配换行符
                Console.WriteLine(Regex.IsMatch("a\nb", "^a.{1}b$", RegexOptions.Singleline));// ^匹配字符串开头,$能匹配字符串结尾
                Console.WriteLine(Regex.IsMatch("\nab", "^ab", RegexOptions.Singleline));// ^不能匹配行开头
                Console.WriteLine(Regex.IsMatch("ab\n", "ab$", RegexOptions.Singleline));// $能匹配行结尾

                //多行模式
                Console.WriteLine(Regex.IsMatch("a\nb", "a.{1}b", RegexOptions.Multiline));// .不能匹配换行符
                Console.WriteLine(Regex.IsMatch("ab", "^ab$", RegexOptions.Multiline));// ^匹配字符串开头,$能匹配字符串结尾
                Console.WriteLine(Regex.IsMatch("\nab", "^ab", RegexOptions.Multiline));// ^能匹配行开头
                Console.WriteLine(Regex.IsMatch("ab\n", "ab$", RegexOptions.Multiline));// $能匹配行结尾
                Console.WriteLine(Regex.IsMatch("\nab\n", "^ab$", RegexOptions.Multiline));// ^能匹配行开头,$能匹配行结尾
            }
        }
    }
  • 相关阅读:
    函数
    函数式编程
    高级特性
    内建的数据结构
    条件语句和循环语句
    java_基础——用代码编译.java文件+加载class文件
    日期格式私人定制——SimpleDateFormat
    java7(3)——增强的catch之自动释放资源
    java7(2)——使用mutilcatch注意事项
    java7(1)——反编译深入理解增强的switch(读字节命令实战)
  • 原文地址:https://www.cnblogs.com/mxw09/p/1784367.html
Copyright © 2011-2022 走看看