• 正则表达式java,javaScript应用


    dfa nfa 混合;捕获;断言;

     正则引擎大体上可分为不同的两类:DFA和NFA,而NFA又基本上可以分为传统型NFA和POSIX NFA。
     
    1.正则语法

      捕获组:

        没用()的字符都是一个一个捕获的从左往右,要么就是一个字符一个字符匹配

          (pattern):捕获该匹配的子表达式;可用$1,$2,$3获得

          (?:pattern):匹配但不捕获正则表达式,,即用$1,$2不能获得

        例如:((A)(B(C))):有四个组:(C);(B(C));(A);((A)(B(C)))

        js中:$1能获得分组值;java中matcher的group(0)能获得分组

      断言:(我猜匹配对象前面是什么;后面是不能是什么;前面是什么;前面不能是什么)

        1.断言后面是什么(?=pattern):Windows (?=95|98|NT|2000)断言Windows后面的是95或者98或者2000

        2.断言后面不是什么(?!pattern): Windows (?=95|98|NT|2000)断言Windows后面的不是95或者98或者2000

        3.断言前面是什么(?<=pattern): (?<=95|98|NT|2000)Windows断言Windows前面的是95或者98或者2000

        4.断言前面不是什么(?<!pattern):(?<!95|98|NT|2000)Windows断言Windows前面的是95或者98或者2000

      表达式:

        [abc]:方括号间的任意字符;[^abc]:任何不在方括号间的文字

        [0-9]:0到9间的数字;[a-z][A-Z][A-z][adgk][]

        (x|y):查找任何匹配项

      ---------------------------------------

      元字符:

        d;s:空白字符;:匹配单子边界;uxxxx:查找以16进制数xxxx规定的Unicode字符

        .;w:单词字符;W:非单词字符;d ;D;s;S;:匹配一个单词边界即与单词与空格的位置("er"匹配"never"中的"er",但不匹配"verb"中的"er")

        ;B("erB"匹配"verb"中的"er",但不匹配"never"中的"er");:null字符; 换行符;f:换页; :回车符; :制表符;

        v:垂直制表符;xxx:以八进制规定的字符;xdd:十六进制的字符;

      量词:

        n+:1到多;n*:0到多;n?:0到1

        {X} ;{X,};{X,Y};

        ^n:以开头;n$:以结尾;

        ?=n:其后紧跟字符串n的字符串;?!n:没有紧接字符串n的字符串  

      修饰符:

        i;g:执行全局匹配;m:多行匹配

    2.javaScript中的应用

      语法:/正则表达式主体/修饰符(可选)

      1)RegExp对象:预定义了属性和方法的表达式对象

        语法:var patt=new RegExp(pattern,modifiers);var patt=/pattern/modifiers;

    var re = new RegExp("\w+");
    var re = /w+/;

        /w/就是一个RegExp对象

        test():只是测试是否能匹配上

        exec():匹配到的结果存在数组中,需要注意的是:匹配到数组的原则:先整体匹配结果-》RegExp.$1->RegExp.$2

        compile():编译正则表达式没什么用

        例子:

            var patt1=new RegExp("The\sbest");
            var patt2=new RegExp("(The)\s(best)");
            var aa=patt1.exec("The best things in life are free");
            console.log(aa);

       2)字符串方法:

        search:获得查找匹配字符串起始位置放回int:var str="Mr. Blue has a blue house";str.search(/blue/i)//结果4

        match:找到一个或多个正则表达式的结果;返回Arrary;也能获得分组$1,$2的值例如:$1 = RegExp.$1

        replace:str.replace(/blue/g,"red");替换后返回新的字符串

        split:string.split(separator,limit):按匹配的结果分隔;返回数组

    3.java中的应用:java.util.regex提供了下面三个类

      Pattern ;Matcher ;PatternSyntaxException

      Pattern.matches(pattern,content):可以判断content中是否有pattern匹配,不需要Pattern实例

      一般我们用java正则需要创建Matcher对象:Pattern p = Pattern.compile(pattern)->Matcher m = p.matcher(content)->之后在对matcher对象做处理

      索引方法:start() ;start(int group);end();end(int group)

      研究方法:lookingAt() ;find() ;find(int start);matches() 

      替换方法:appendReplacement(StringBuffer sb, String replacement);appendTail(StringBuffer sb);replaceAll(String replacement) ;replaceFirst(String replacement);quoteReplacement(String s) 

        //直接使用Pattern
        public static void regexTest1(){
            String content = "I am noob from runoob.com.";
            String pattern = ".*runoob.*";
            boolean isMatch = Pattern.matches(pattern, content);//是否匹配不需要实例
            Pattern p = Pattern.compile(pattern);                //创建实例对象
            Matcher m = p.matcher(content);                        //创建Matcher对象
            while(m.find()){
                System.out.println(m.group(0));
                //System.out.println(m.group(1));
            }
            System.out.println("1.matches:字符串中是否包含了 'runoob' 子字符串? " + isMatch);
        }
        //Matcher 类的方法
        //1.索引方法:start;end;
        public static void regexTest2(){
            String REGEX = "\bcat\b";
            String INPUT = "cat cat cat cattie cat";
            int count = 0;
            //获得matcher对象
            Pattern p = Pattern.compile(REGEX);
            Matcher m = p.matcher(INPUT);
            while(m.find()){
                count++;
                System.out.println("Match number "+count);
                System.out.println("start(): "+m.start());//返回以前匹配的初始索引必须之前要有匹配
                System.out.println("end(): "+m.end());//返回以前匹配的结束索引必须之前要有匹配
            }
        }
        //2.研究方法:matches 与lookingAt 方法区别:matches尝试整个区间匹配;lookingAt只匹配开头部分
        public static void regexTest3(){
            String REGEX = "foo";
            String INPUT = "fooooooooooooooooo";
            String INPUT2 = "ooooofoooooooooooo";
            Pattern pattern = Pattern.compile(REGEX);
            Matcher matcher = pattern.matcher(INPUT);
            Matcher matcher2 = pattern.matcher(INPUT2);
            //测试
            System.out.println("Current REGEX is: "+REGEX);
            System.out.println("Current INPUT is: "+INPUT);
            System.out.println("Current INPUT2 is: "+INPUT2);
            System.out.println("lookingAt():"+matcher.lookingAt());
            System.out.println("matches():"+matcher.matches());
            System.out.println("lookingAt():"+matcher2.lookingAt());
        }
        //3.替换方法:replace;replaceAll:不同在与:replaceFirst匹配第一个;replaceAll匹配所以
        public static void regexTest4(){
            String REGEX = "dog";
            String INPUT = "The dog says meow.All dogs say meow.";
            String REPLACE = "cat";
            Pattern p = Pattern.compile(REGEX);
            Matcher m = p.matcher(INPUT);
            System.out.println(m.replaceFirst(REPLACE));//只匹配第一个
            System.out.println(m.replaceAll(REPLACE));//全部匹配
        }
        //4.appendReplacement 和 appendTail:用于文本替换
        public static void regexTest5(){
            String REGEX = "a*b";
            String INPUT = "aabfooaabfooabfoob";
            String REPLACE = "-";
            Pattern p = Pattern.compile(REGEX);
            Matcher m = p.matcher(INPUT);
            StringBuffer sb = new StringBuffer();
            while(m.find()){
                m.appendReplacement(sb, REPLACE);
            }
            m.appendTail(sb);
            System.out.println(sb);
        }
    View Code

     4.NFA/DFA算法:将正则表达式转为机器语言加识别速度

      ε边存在的最大的理由:使用ε边来给出一个简洁的算法把一个正则表达式转换成ε-NFA。

      状态机分类:确定的有穷状态自动机(DFA);非确定的有穷状态自动机(NFA);带有ε边的非确定的状态机(ε-NFA)

      1)从正则表达式到ε-NFA

        正则表达式有规则的串联、并联、重复、可选等操作;对应的ε-NFA也需要规定出对应的规则

        1.字符集:直接按步骤走即可

        2.串联:一个状态图结束走后直接下一个状态图

      

        3.并联:每个状态图,开始结束都用一个start,end连接(ε)

        4.重复:当状态走到结束状态的时候,如果遇到一个可以让规则接受的字符串,则再次回到结束状态

         5.可选:规则的状态图的起始状态和结束状态连接起来

        如果重复使用的是0次以上重复,也就是原来的重复加上可选的结果,那么可以简单地把图4.4的Start状态去掉,让End状态同时拥有起始状态和结束状态两个角色,[Start]和[End]则保持原状。

        作用:将5种构造状态图的办法都对应到了5种构造规则的办法上了。对于 任意的一个正则表达式,我们仅需要把这个表达式还原成那5种构造的嵌套,然后把每一步构造都对应到一个状态图的构造上,就可以将一个正则表达式转换成一个 ε-NFA了

        6.用法例子:

          正则表达式:((aa|bb)|((ab|ba)(aa|bb)*(ab|ba)))*

          状态机:

        7.消除非确定性:只得到ε-NFA还是不行的,因为ε-NFA的不确定性太大了,直接根据ε-NFA跑的话,每一次都会得到大量的临时状态集合,会极大地降低效率

          1)消除ε边算法

          2)

    -------------------------太多了还不怎么能用到不看了NFA/DFA链接大家自己看看把

      

  • 相关阅读:
    vue长按事件
    video标签视频自动播放
    express路由的使用
    Java的堆栈和堆
    MongoDB建库db、建集合collection以及其他常用命令
    计算机网络基础-目录
    如何清除tomcat缓存
    tomcat/logs目录下各日志文件的解析
    在Windows系统和Linux服务器安装MongoDB和基本使用
    [转]/tomcat/conf/server.xml配置文件的源码解析
  • 原文地址:https://www.cnblogs.com/xiaoping1993/p/7116722.html
Copyright © 2020-2023  润新知