bw*q[^u]w*b匹配包含后面不是字母u的字母q的单词。但是如果多做测试(或者你思维足够敏锐,直接就观察出来了),你会发现,如果q出现在单词的结尾的话,像Iraq,Benq,这个表达式就会出错。这是因为[^u]总要匹配一个字符,所以如果q是单词的最后一个字符的话,后面的[^u]将会匹配q后面的单词分隔符(可能是空格,或者是句号或其它的什么),后面的w*b将会匹配下一个单词,于是bw*q[^u]w*b就能匹配整个Iraq fighting。负向零宽断言能解决这样的问题,因为它只匹配一个位置,并不消费任何字符。现在,我们可以这样来解决这个问题:bw*q(?!u)w*b。
零宽度负预测先行断言(?!exp),断言此位置的后面不能匹配表达式exp。例如:d{3}(?!d)匹配三位数字,而且这三位数字的后面不能是数字;b((?!abc)w)+b匹配不包含连续字符串abc的单词。
同理,我们可以用(?<!exp),零宽度负回顾后发断言来断言此位置的前面不能匹配表达式exp:(?<![a-z])d{7}匹配前面不是小写字母的七位数字。
一个更复杂的例子:(?<=<(w+)>).*(?=</1>)匹配不包含属性的简单HTML标签内里的内容。(?<=<(w+)>)指定了这样的前缀:被尖括号括起来的单词(比如可能是<b>),然后是.*(任意的字符串),最后是一个后缀(?=</1>)。注意后缀里的/,它用到了前面提过的字符转义;1则是一个反向引用,引用的正是捕获的第一组,前面的(w+)匹配的内容,这样如果前缀实际上是<b>的话,后缀就是</b>了。整个表达式匹配的是<b>和</b>之间的内容(再次提醒,不包括前缀和后缀本身)。
这个解读
1、<span后面的/s*? 主要是考虑<span >与<span>都考虑在内
s匹配空字符*表示多个空字符都可以,?是表示前面的可有可无。
2、(?!:style) 表示右侧不能有style的才可以匹配,因为有的肯定有用。而且不获取,所以这个括号不是$1
3、(.[^<>]*) 就是匹配<span></span>中间的数据了。
这两天刚开始研究这个,写了好几个正则,先分享出来,看大家能看懂吗
//加强替换主要是考虑多个br的问题
function doRepAdvance(s){
var str=s.replace(/<p><br type="_moz">s*?</p>/ig,"");
str=str.replace(/<p>s*<br type="_moz">s*</p>/ig, "");
str=str.replace(/<p>s*?<brs?/?>s*?</p>/ig, "");
str=str.replace(/<p>(s| | | |xc2xa0)*</p>/ig, "");
str=str.replace(/<p>s*?</p>/ig,"");
str=str.replace(/<p> </p>/ig,"");
str=str.replace(/<br type="_moz">n </p>/ig, "</p>");
str=str.replace(/<br type="_moz">s*?</p>/ig, "</p>");
str=str.replace(/<brs?/?>s*?</p>/ig, "</p>");
str=str.replace(/<br />n </p>/ig, "</p>");
str=str.replace(/<br>n </p>/ig, "</p>");
//多个br
str=str.replace(/(<br type="_moz">s*)+</p>/ig, "</p>");
str=str.replace(/(<brs?/?>s*)+</p>/ig, "</p>");
//空标签
str=str.replace(/<p style=["'].[^<>]*["']>/ig, "<p>");
str=str.replace(/<span style="background-color: initial;">/ig, "<span>");
//没有style的span去掉
str=str.replace(/<spans*?(?!:style)>(.[^<>]*)</span>/ig,"$1");
str=str.replace(/<([a-z]+?)(?:s+?[^>]*)?>(s| )*?</1>/ig, "");
//str=str.replace(/<([a-z]+?)(?:s+?[^>]*)?>s*?</1>/ig, "");
return str;
}









