当一个表达式中有多个非贪婪匹配,以表达式 "d(\w+?)d(\w+?)z" 为例,对于第一个括号中的 "\w+?" 来说,右边的 "d(\w+?)z" 属于它的 "右侧的表达式",对于第二个括号中的 "\w+?" 来说,右边的 "z" 属于它的 "右侧的表达式"。
当 "z" 匹配失败时,第二个 "\w+?" 会 "增加匹配一次",再尝试匹配 "z"。如果第二个 "\w+?" 无论怎样 "增加匹配次数",直至整篇文本结束,"z" 都不能匹配,那么表示 "d(\w+?)z" 匹配失败,也就是说第一个 "\w+?" 的 "右侧" 匹配失败。此时,第一个 "\w+?" 会增加匹配一次,然后再进行 "d(\w+?)z" 的匹配。循环前面所讲的过程,直至第一个 "\w+?" 无论怎么 "增加匹配次数",后边的 "d(\w+?)z" 都不能匹配时,整个表达式才宣告匹配失败。
其实,为了使整个表达式匹配成功,贪婪匹配也会适当的“让出”已经匹配的字符。因此贪婪匹配也有类似的情况。当一个表达式中有较多的未知匹配次数的表达式时,为了让整个表达式匹配成功,各个贪婪或非贪婪的表达式都要进行尝试减少或增加匹配次数,由此容易形成一个大循环的尝试,造成了很长的匹配时间。本文之所以称之为“陷阱”,因为这种效率问题往往不易察觉。
举例:"d(\w+?)d(\w+?)d(\w+?)z" 匹配 "ddddddddddd..." 时,将花费较长一段时间才能判断出匹配失败 。这里所说的情况是不是这样的啊?以dddddd为例类似这样的
1. a 不能匹配表达式,继续吃 
2. a= 不能匹配表达式,继续吃 
3. a== 不能匹配表达式,继续吃 
4. a=== 不能匹配表达式,继续吃 
5. a==== 不能匹配表达式,继续吃 
6. a===== 不能匹配表达式,继续吃 
7. a=====b 呵呵,终于能匹配表达式了
的步骤,大家能不能帮我列一下啊这里的"增加匹配次数"的意思不是很懂,大家能不能跟我讲一下,它的匹配顺序啊?

解决方案 »

  1.   

    这个就有点复杂了,这需要了解正则表达式引擎(NFA 或 DFA)是如何工作的。具体的也没怎么研究过,建议可以看看 Mastering Regular Expressions 一书,里
    面有详细的说明。
      

  2.   

    ^(?x)\\p{Alnum}+(?#aaaa)$这里我加个注释,怎么不行啊?
      

  3.   

    Java 中不支持 (?#) 的内嵌注释,可以改为:^\\p{Alnum}+(?x:aaaa\n)$ 或者启用注释模式(忽略所有的空白字符,且以 ## 至行结束符的为注释)String regex = "(?x:            \n" +
                   "     \\p{Alnum} \n" +
                   "     ## aaaa    \n" +
                   ")";
      

  4.   

    对于一些复杂的正则表达式需要写一些注释,否则今后就很难对其进行维护。具体的格式,在我的 blog 里有一篇文章中的代码里可以看到(是仿照 Matering Regular Expressions 一书的格式)http://blog.csdn.net/bao110908/archive/2008/02/29/2132973.aspx
      

  5.   

    NFA是贪婪匹配模式吧 而DFA是最小匹配模式的吧 。MS而已不是很了解
    在考试。。考好就去看