正則表達(dá)式不包含屬性
正則:<img(?![^<>]*?alt[^<>]*?>).*?>
例子:<img src="" alt=""> <img src="" > <img src="" title=""> <img src="" id=""> <img src="" title="" alt="">
擴(kuò)展,如果要找沒(méi)有帶title屬性的a應(yīng)該是:
正則:<a(?![^<>]*?title[^<>]*?>).*?>
例子:<a src="" alt=""> <a src="" > <a src="" title=""> <a src="" id=""> <a src="" title="" alt="">
用正則表達(dá)式找出不包含連續(xù)字符串a(chǎn)bc的單詞
[^abc]表示不包含a、b、c中任意字符, 我想實(shí)現(xiàn)不包含字符串a(chǎn)bc應(yīng)該如何寫表達(dá)式?
就我自己而言,這個(gè)問(wèn)題最簡(jiǎn)單的解決方法是使用編程語(yǔ)言的配合,找出那些包含abc的,剩下的就是不包含的了——懶人的風(fēng)格。但我寫的是教程,讀者未必都有編程的基礎(chǔ),有些只是使用一些工具從txt文檔中抽取出一些信息,所以要回答還是必須完全通過(guò)正則表達(dá)式來(lái)完成。
于是打開了RegexTester,開始試驗(yàn),先是試了使用((?'test'abc)|.)*(?(test)(?!))(含意是:查找abc,或任意的字符,如果找到了abc,就把它存入命名為test的組里,到最后檢查test組里是否有內(nèi)容,如果有就匹配失敗,相關(guān)說(shuō)明見教程),結(jié)果是"abc","aabc","abcd","aa"都能通過(guò)測(cè)試,看來(lái)是到最后測(cè)試到test組存在后又回溯了,此解決方案不可行。
然后又試了(.(?!abc))*(找出所有后面不是abc的字符),結(jié)果是"abc","abcd"通過(guò)測(cè)試,"aabc"則只截取了后面的"abc",顯然不行。
那加強(qiáng)條件試試:((?<!abc).(?!abc))*(找出所有前面和后面都不是abc的字符),結(jié)果是所有包含abc的字符串都只截取了里面的"abc",不包含abc的則直接通過(guò)。
現(xiàn)在看來(lái)有點(diǎn)戲了,但是怎么把那些內(nèi)部包含abc的字符串過(guò)濾掉呢?這個(gè)問(wèn)題換句話說(shuō)也就是怎么匹配整體而不是部分呢?現(xiàn)在需要明確用戶的需求了:如果用戶想要找的是單詞,那就在表達(dá)式的兩端加上\b,如果要找的是行,就加上^和$。由于用戶的問(wèn)題沒(méi)有明確說(shuō)明,我就當(dāng)作是單詞吧。
于是等到了這樣的表達(dá)式:\b((?<!abc).(?!abc))*\b,經(jīng)過(guò)測(cè)試,這個(gè)表達(dá)式能匹配所有不包含abc的單詞,以及單詞abc。
怎么排除單詞abc?經(jīng)過(guò)一番思考,最后我認(rèn)為判斷單詞是否以a開頭的方式最為方便:\b(a(?!bc)|[^a](?!abc))((?<!abc).(?!abc))*\b(要么以后面不是bc的a開頭,要么不以a開頭,除了開頭后面所有的字符必須前面和后面都不是abc)。經(jīng)過(guò)測(cè)試,完全滿足要求,Bingo!
使用正則表達(dá)式查找不包含連續(xù)字符串a(chǎn)bc的單詞,最終結(jié)果:\b(a(?!bc)|[^a](?!abc))((?<!abc).(?!abc))*\b
----------------
更新:根據(jù)maple的評(píng)論,更簡(jiǎn)潔的作法是:\b((?!abc)\w)+\b
正則表達(dá)式-不包含某個(gè)字符串
在使用正則表達(dá)式的場(chǎng)合,常常有這種需求,就是匹配一個(gè)不包含某個(gè)子串的子符串。比如說(shuō),我要從“eabcdfgh”得到"cd"之前的子串。有些人可能會(huì)寫:
([^cd]*)
這種寫法是徹底錯(cuò)誤的,因?yàn)閇]中的是集合,也就是說(shuō),[^cd]表示不等于c或者d,而不是cd。下面的程序中沒(méi)有cd,但eab還是被匹配出來(lái)了。
String s = "([^cd]*)";
Match m = Regex.Match("eabcfgh", s);
MessageBox.Show(m.Value);//eab
MessageBox.Show(m.Groups[1].Value);//eab
上面這種寫法是錯(cuò)的比較離譜的,正常青年一般都可以避免這種錯(cuò)誤。在特殊情況下,正則表達(dá)式可以這么寫,而且效率是比較高的。
([/s/S]*cd)
先說(shuō)明下/s/S是表示匹配任何字符。所謂特殊情況,就是我知道這個(gè)字符串中必有cd的存在。假如,我的要求是匹配不包含cd的部分(為了描述方便,只匹配cd之前的部分),也就是說(shuō),當(dāng)cd不存在時(shí),應(yīng)該把整個(gè)字符串都取出來(lái)。
String s = "((.(?!cd))*.)";
//String s = "([/s/S]*cd)";
Match m = Regex.Match("eabcdfgh", s);
MessageBox.Show(m.Value);//eab
MessageBox.Show(m.Groups[1].Value);//eab
這種寫法終于符合要求了。不過(guò)值得一提的是,相較前一種而言,它的效率比較低。
回顧一下相關(guān)的語(yǔ)法:
(?:子表達(dá)式) 定義非捕獲組。
//定義非捕獲組
String s = "e(?:ab)(.*)";
Match m = Regex.Match("eabcd", s);
MessageBox.Show(m.Value);//eabcd
MessageBox.Show(m.Groups[1].Value);//cd
ab是被匹配的,但是它所在的組沒(méi)有被捕獲,Group[1]是cd
(?=子表達(dá)式) 零寬度正預(yù)測(cè)先行斷言。
//零寬度正預(yù)測(cè)先行斷言
//String s = "b(cd|de)(.*)";
String s = "b(?=cd|de)(.*)";
Match m = Regex.Match("eabcdfg", s);
MessageBox.Show(m.Value);
MessageBox.Show(m.Groups[1].Value);//區(qū)別 cd cdfg
這種寫法和注釋掉的寫法是有區(qū)別的,區(qū)別就是“零寬度”,這種寫法會(huì)被捕獲,也就是不占一個(gè)Group。
(?!子表達(dá)式) 零寬度負(fù)預(yù)測(cè)先行斷言。
!表示非,就是不包含,同樣是零寬度,不會(huì)被捕獲。
(?<=子表達(dá)式) 零寬度正回顧后發(fā)斷言。
例:(?<=19)\d{2}\b
“1851 1999 1950 1905 2003”中的“99”、“50”和“05”
(?<!子表達(dá)式) 零寬度負(fù)回顧后發(fā)斷言。
例:(?<!19)\d{2}\b
“1851 1999 1950 1905 2003”中的“51”和“03”
相關(guān)文章
JS正則表達(dá)式必須包含數(shù)字、字母、特殊字符
這篇文章主要介紹了JS正則表達(dá)式必須包含數(shù)字、字母、特殊字符的相關(guān)資料,文中還給大家提到了js 正則表達(dá)式 匹配除漢字,字母,數(shù)字,逗號(hào),句號(hào)外的特殊字符(用來(lái)規(guī)范輸入內(nèi)容) 需要的朋友可以參考下2019-08-08WEB開發(fā)時(shí)常用的正則表達(dá)式(PHP和Javascript)
這篇文章主要介紹了WEB開發(fā)中最常用最實(shí)用的正則表達(dá)式及其用法,需要的朋友可以參考下2015-10-10好東西,老外用正則表達(dá)式寫的HTML分離函數(shù)
好東西,老外用正則表達(dá)式寫的HTML分離函數(shù)...2006-06-06JScript中正則表達(dá)函數(shù)的說(shuō)明與應(yīng)用
JScript中正則表達(dá)函數(shù)的說(shuō)明與應(yīng)用...2007-04-04js處理網(wǎng)頁(yè)編輯器轉(zhuǎn)義、去除轉(zhuǎn)義、去除HTML標(biāo)簽的正則
這篇文章主要介紹了富文本編輯器生成的HTML標(biāo)簽,進(jìn)行轉(zhuǎn)義,然后寫入數(shù)據(jù)庫(kù),防止腳本注入,需要的朋友可以參考下2020-02-02