Tempered Greedy Token – 在负面预测之前放置点有什么不同
<table((?!</table>).)*</table> 匹配我所有的表标签,但是,
 <table(.(?!</table>))*</table> 
才不是。 第二个似乎是有道理的,如果我试图用文字写出expression,但我不能理解第一个。
有人可以向我解释这个区别吗?
作为参考,我从这里得到了“Tempered Greedy Token”这个词: http : //www.rexegg.com/regex-quantifiers.html#tempered_greed
 由于Google在tempered greedy token的结果中回报了这个问题,所以我觉得有必要提供一个更全面的答案。 
什么是脾气暴躁的令牌?
rexegg.com 脾气贪婪的标记引用是相当简洁的:
在
(?:(?!{END}).)*,*量词适用于一个点,但现在是一个回火点。 负向前瞻(?!{END})声明跟在当前位置之后的不是string{END}。 因此,点不能匹配{END}的开始大括号,保证我们不会跳过{END}分隔符。
那就是: 脾气暴躁的标记是一种字符序列的 否定字符类 (比较单个字符的 否定字符类 )。
  注意 : 脾气暴躁的标记和否定的字符类之间的区别在于 ,前者与序列本身以外的文本并不真正匹配,而是单个字符不会启动该序列。 即(?:(?!abc|xyz).)+在defabc不会与def相defabc ,但会匹配def 和 bc ,因为a启动被禁止的abc序列,而bc不会。 
它包括:
-   (?:...)*– 一个量化的非捕获组(它可能是一个捕获组,但是捕获每个单独的字符是没有意义的)(a*可以是+,这取决于空string匹配是预期)
-   (?!...)– 实际上对当前位置右侧的值施加限制的负向预测
-  .– (或任何(通常是单个)字符)消费模式。
 然而,我们总是可以通过使用反向预测(例如(?!{(?:END|START|MID)}) )中的交替或通过用否定的字符类replace全匹配的点来进一步调节令牌(例如(?:(?!START|END|MID)[^<>])当试图匹配只在标签内的文本)。 
消费部分安置
 请注意,没有提到消费部分(最初的脾气暴躁的代币中的点)被放置在前瞻之前的构造。  Avinash的答案是清楚地解释这一部分: (.(?!</table>))*首先匹配任何字符(但没有DOTALL修饰符的换行符),然后检查是否没有遵循</table>导致失败匹配<table>table</table>中的e 。  消费部分( . )必须放在回火预见之后 。 
什么时候使用脾气暴躁的代币?
Rexegg.com给出了一个想法:
-  当我们想在分隔符1和分隔符2之间匹配一个没有子串3(例如{START}(?:(?!{(?:MID|RESTART)}).)*?{END}
-  当我们想要匹配一个包含特定模式的文本块而不溢出后续的块(例如,而不是像<table>.*?chair.*?</table>的懒点匹配)时,我们会使用类似<table>(?:(?!chair|</?table>).)*chair(?:(?!<table>).)*</table>)。
-  当我们想要匹配2个string之间可能的最短窗口。 当你需要得到abc 2 xyz时,懒惰的匹配将无济于事abc 2 xyzabc 1 abc 2 xyz(见abc.*?xyz和abc(?:(?!abc).)*?xyz)。
性能问题
贪婪的贪婪标记是耗费资源的,因为在每个与消费模式匹配的字符之后执行预先检查。 展开循环技术可以显着提高贪婪的贪婪标记性能。
 比方说,我们想在abc 1 abc 2 xyz 3 xyz中匹配abc 2 xyz xyz 。 而不是使用abc(?:(?!abc|xyz).)*xyz检查abc和xyz之间的每个字符abc(?:(?!abc|xyz).)*xyz ,我们可以用[^ax]*跳过所有不是a或x字符,然后匹配所有没有跟随bc (带有a(?!bc) )和所有没有跟随yz (带有x(?!yz) )的x(?!yz) : abc[^ax]*(?:a(?!bc)[^ax]*|x(?!yz)[^ax]*)*xyz 。 
  ((?!</table>).)*将检查要匹配的特定字符不能是string</table>的起始字符。 如果是,那么只有它匹配那个特定的字符。  *重复相同的零次或多次。 
  (.(?!</table>))*只有在没有</table>才会匹配任何字符,零次或多次。 所以这将匹配表标签内的所有字符excpet最后一个字符,因为最后一个字符后面是</table> 。 下面的模式</table>声明在比赛结束时必须有一个closures表格标签。 这使比赛失败。 
看到这里
温和的贪婪标记实际上意味着:
“匹配,但只能达到一个点”
你如何做到这一点:
你把你不想匹配的标记作为一个负面的前瞻
(?!notAllowedToMatch)在一个点的前面.(匹配任何一件事),那么你重复整个事情与星*:
((?!notAllowedToMatch).)*
怎么运行的:
“看,吃”一遍又一遍,通过inputstring从左到右移动一个字符 ,直到看到不允许的序列(或string的结束),此时匹配停止。
Wiktor的更详细的答案是好的,我只是想一个简单的解释是为了。