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。里面对中文的匹配还是挺有用的。

  • 相关阅读:
    Java实现 蓝桥杯VIP 算法训练 数的统计
    Java实现 蓝桥杯VIP 算法训练 和为T
    Java实现 蓝桥杯VIP 算法训练 友好数
    Java实现 蓝桥杯VIP 算法训练 连续正整数的和
    Java实现 蓝桥杯VIP 算法训练 寂寞的数
    Java实现 蓝桥杯VIP 算法训练 学做菜
    Java实现 蓝桥杯VIP 算法训练 暗恋
    Java实现 蓝桥杯VIP 算法训练 暗恋
    测试鼠标是否在窗口内,以及测试鼠标是否在窗口停留
    RichEdit 各个版本介绍
  • 原文地址:https://www.cnblogs.com/549294286/p/2665581.html
Copyright © 2011-2022 走看看