zoukankan      html  css  js  c++  java
  • 正则表达式的基本概念和原理

    元字符(metacharacter)

    正则引擎保留字符,作为一般字符匹配时需要转义

    流派(flavor)

    不同工具支持的元字符和特性各不相同,构成正则表达式的不同流派。

    子表达式(subexpression)

    括号内的表达式,常用于获取部分匹配结果

    字符(character)

    正则表达式的基本构成。需要注意不同编码下字符的意义不同,大多数工具只支持ascii编码的字节匹配,近来有部分工作支持unicode编码匹配。

    简记字符(shorthands)

    \t \n \r;  \s 与  \S, \w 与 \W, \d 与 \D

    \b (\<与\>)

    使用特定的语言(perl/java/c++)或工具(vim/grep)时需要关注的基本问题:

    1. 支持的元字符号及特性

    2. 工具的交互方式(如何操作,以及目标文本类型)

    3. 正则引擎的类别  (NFA/DFA)

    1.支持的元字符及特性

    (1)POSIX 1986 将各种常见流派分为两大类

    BREs Basic Regular Expressions (grep)

    EREs Extented Regular Expressions (egrep)

    现在两者的差异缩小, 基本差异为grep元字符需要转义 \? \+ \|

    (2)常用元字符和特性 (枯燥,请翻书)

    字符表示: \t \n

    字符组表示: [a-z] [[:alpha:]] 

    锚点: ^ $ \b

    注释: (?#...)

    分组、条件判断: (...) {min, max} + ?  

    2. 不同工具的交互方式

    (1)集成式 perl, awk, 修改直接在目标变量上进行,函数或对象式  java,.net, php, c++,  不修改目标变量,直接传回匹配结果。

    (2)工具本身的字符串元字符不同,譬如 字符串"\\t" 传给正则引擎的是 "\t";

    (3)对文本编码的支持。如 perl中^.$无法匹配"你"而必须使用^...$ , 而egrep 可以

    (4)匹配模式。不区分大小写/是否忽略[]外的空白字符/是否支持. 匹配换行符

    (3)正则引擎的分类

    表达式主导的NFA(非确定有穷自动机)  (大多数非GNU版本的awk, egrep)和 文本主导的DFA(确定有穷自动机) (perl,php,java,.net)

    相同的规则(最左最长规则 )

    1. 优先选择最左端的匹配结果。如 a|b 匹配字符串'the b is before a', 匹配成功的是'b'

    2. 标准量词优先匹配(? * + {min,max})。 greedy, 尽可能匹配多的字符。如^.*([0-9]+)匹配字符串'copyright 2011.' 时子表达式匹配的是 3

        但DFA取绝对最长,如one(self)?(oneselfsufficient)? 匹配 oneselfsufficient ,DFA匹配整各串, 传统型NFA 匹配oneself

        (| 不是标准量词,也往往是NFA和DFA的区分点 , 传统型NFA使用按序匹配)

    不同的规则

    1. 匹配方法。NFA只扫描一次表达式,DFA只扫描一次目标文本。to(nite|knight|night) 匹配 tonight, NFA的扫描是确定 to,然后nite, knight, night 依次尝试,即目标文本中的ni被扫描两次, 而DFA则同时纪录所有可能的匹配,同样的例子,扫描到目标文本toni 时,DFA引擎已经记录 to(ni,te | knight | ni,ght) 中两种可能匹配。

        注:这个差异意味这DFA的匹配时间复杂度取决于目标文本的大小,与正则表达式的写法无关。而NFA会多次扫描文本,不同正则表达式写法对匹配性能影响巨大。

    2.NFA回溯的两个基本规则

       应该首先选择那个分支? 匹配优先量词(* + ? {min, max})优先选择尝试,忽略优先量词 (*? +? ?? {min, max}?) 优先选择放弃尝试。[真变态啊!:-(] 

       匹配失败后应该选择哪个候选分支? 最后存储的 

       sample: ab?c 匹配 abX

     “|"的顺序匹配陷阱

    使用 (0?[1-9] | [12][0-9] | 3[01])匹配 Jan 31

    why NFA?

    NFA编译时间更快,需要的内存更少

    NFA提供反向引用,环视,非优先匹配量词,固化分组

    注: POSIX NFA为使用NFA原理,同时需要模拟某些DFA特性(如绝对最长匹配)而做,性能相对较差, 相应的工具也较少。

  • 相关阅读:
    Mac终端编写c语言程序方法
    X-code最常用快捷键
    类方法和实例方法区别
    一、SQL语句中的增、删、查、改
    从零开始,学习web前端之HTML基础
    图片 自适应 容器大小
    Java第二天 数据类型
    Java 第一天
    javascript的基础知识
    JavaScript(一)
  • 原文地址:https://www.cnblogs.com/wangshi/p/2291822.html
Copyright © 2011-2022 走看看