zoukankan      html  css  js  c++  java
  • 【正则】正则表达式和自动机

    最近在看,先留个链接

    http://passover.blog.51cto.com/2431658/425536

    有穷自动机(Finite Automate)是用来模拟实物系统的数学模型,它包括如下五个部分:

      • 有穷状态集States
      • 输入字符集Input symbols
      • 转移函数Transitions
      • 起始状态Start state
      • 接受状态Accepting state(s)
    正则表达式就是建立在自动机的理论基础上的:用户写完正则表达式之后,正则引擎会按照这个表达式构建相应的自动机(可能是NFA,也可能是DFA,但它们必定是等价的),若输入一串文本之后,自动机抵达了接受状态,则这串文本可以“匹配”用户指定的正则表达式。
    NFA

    【转载】有穷自动机 - 轩辕惊鸿 - 龙潭~

    DFA

    【转载】有穷自动机 - 轩辕惊鸿 - 龙潭~

    DFA引擎在任意时刻必定处于某个确定的状态,而NFA引擎可能处于一组状态之中的任 何一个,所以,NFA引擎必须记录所有的可能路径(trace multiple possible routes through the NFA),NFA之所以能够提供Backtrack的功能,原因就在这里。

     

    http://tianle52.blog.163.com/blog/static/25513217201122581486/

    正则使用的时候一定要注意他的自动机特性,具体来说就是每个节点只会关注他下一个输入让他达到的状态。有个比较经典的trap,用正则a*?b去匹配 aab,粗看一下肯定以为匹配结果会是ab,其实不然。他先去匹配第一个a,然后去判断下一个是不是b,如果不是,那么再看是不是还是a,所以结果是 aab。

    有几个经验:

    1. 对任意字符进行匹配,可以使用[\s\S],这个是比较常用的习惯,虽然你还能写出很多其他一样功能的正则。

    2. 利用环视来查看匹配结果的前后特征。这个在抽取且不用group的时候会经常用到,这个最好是要知道怎么用。

    3. 去除不需要的group。这个经常会在写取固定的group值的时候会遇到这个麻烦,前面有个匹配不得不用到括号,这样会比预期多出来一个group,那么可以使用(?:xxx)来声明这个括号不是一个group。

    4. 性能问题。其实我个人并不太关注正则表达式的优化,但是有一点是必须要注意的,就是不要使用贪婪的嵌套,这个性能是很低的。

    5. 用使用正则一样的环境来验证正则,比如java的程序需要调用正则,用写个java测试程序来验证。我做过一个简单java正则验证的GUI工具,用了很多年还挺顺手的,放到附件中给大家分享一下吧。

      总的来说,使用正则不要硬搬,关键是掌握原理、灵活运用。希望大家都能把正则用的得心应手。

      最后附一个常用正则的页面,也是很久以前在网上找的http://passover.blog.51cto.com/2431658/425533。里面对中文的匹配还是挺有用的。

  • 相关阅读:
    应用监控CAT之cat-client源码阅读(一)
    java中this的N种使用方法
    微软职位内部推荐-Software Engineer II
    微软职位内部推荐-Software Engineer II
    微软职位内部推荐-Software Engineer II
    微软职位内部推荐-Senior Software Engineer
    微软职位内部推荐-Software Engineer II
    微软职位内部推荐-Senior Software Engineer
    微软职位内部推荐-Software Engineer II
    微软职位内部推荐-Software Engineer II
  • 原文地址:https://www.cnblogs.com/549294286/p/2665581.html
Copyright © 2011-2022 走看看