2013-12-10 163 views
8

與正則表達式如何匹配一個字符串中的東西不是什麼東西?這可能沒有道理,但請繼續閱讀。匹配是什麼東西?

所以取詞baby例如匹配一切不是一個b,你會做這樣的事情[^b]這將匹配ay。夠簡單!但如何在這個字符串Ben sits on a bench我可以匹配所有不是ben所以我會試圖匹配sits on a ch

更好地匹配所有不是模式的東西嗎?例如在1a2be3匹配所有不是number,letter,number,所以它會匹配字符串中除1a2以外的每個組合?

+6

這聽起來像你可以用空字符串做一個正則表達式替換你的黑名單模式,看看是否還有什麼東西? – Jon

+0

你能舉一個例子來回答嗎? – Srb1313711

+1

@ Srb1313711任何編程語言的選擇?我不確定替換是否可以在正則表達式中完成。 – skiwi

回答

0

如果你想匹配除了一個以外的所有單詞,你可以使用負面預測:\b(?!ben\b)\w*\b,但對於你的確切問題的答案喬恩的評論似乎是最簡單的。

+0

這沒有爲我工作我在這裏測試http://gskinner.com/RegExr/與我的本例,它只匹配第一本?你也可以解釋\ b? – Srb1313711

+0

\ b是字邊界,請嘗試在這裏:http://regexpal.com/適合我(雖然不完全符合您的要求,因爲它符合單詞)。 – hillel

1
(?:ben)|(.) 

這是什麼做的正則表達式匹配是ben或任何其他字符,然而,ben沒有捕獲,但其他字符。所以,除了ben之外,你會得到很多比賽。然後你可以將所有這些比賽結合在一起得到沒有ben的字符串。

這裏是一個python的例子。

import re 

thestr = "Ben sits on a bench" 
regex = r'(?:ben)|(.)' 

matches = re.findall(regex, thestr, re.IGNORECASE) 
print ''.join(matches) 

這將輸出繼電器:

sits on a ch 

注意前導空格。您當然可以通過添加.strip()來消除該問題。

另請注意,使用空字符串替換ben以獲得相同結果的正則表達式可能會更快。但如果你想在更復雜的正則表達式中使用這種技術,它可以派上用場。

當然,你也可以把更復雜的正則表達式在ben的地方,所以例如你number,letter,number例子是:

(?:[0-9][a-z][0-9])|(.) 
+0

@ Srb1313711是否爲您解決了這個問題? – rednaw

+0

你可以放一個'*'來匹配其他所有內容,而不是匹配* char * char *並使用'.join'? – ADTC

+0

如果你使用'。*'它可以匹配任何'ben',所以你不能這樣做。 – rednaw

0

好做最簡單的事情是很百搭

(.*?) 

然後在匹配的模式上做另一個匹配你不想要的東西(例如,在perl中,你將在變量$ &中匹配該模式)。

如果它匹配,這不是你想要的,你有你的匹配。

簡單的A-B,其中A是一切(。*?),B是你不想要的。所以你最終做了兩場比賽,但我認爲沒關係。

0

只需替換匹配的所有內容帶空白(刪除它)的圖案。

您還沒有表明你正在使用的語言,所以基因:

s/ben//g 

和其他範例:

s/\d[a-zA-Z]\d//g 
+0

我希望匹配不會取代,這可能工作,但不是什麼即時通訊尋找,但謝謝你的答案! – Srb1313711

0

如果你想字符串列表,使用「正則表達式上的分裂」而不是「正則表達式匹配」。

1

簡答:你不能做你在問什麼。從技術上講,第一部分有一個醜陋的答案,但第二部分(據我瞭解)沒有答案。對於你的第一部分,我有一個非常不切實際的(但純正則表達式)的答案;但是,我有一個非常不切實際的(但純正則表達式)答案;我有一個非常不切實際的(但純正則表達式)答案;我有一個非常不切實際的(但純正則表達式)答案;任何更好的將需要代碼(就像@ rednaw上面更清晰的答案)。我加入了測試,以使其更全面。 (爲了簡單起見,我使用grep -Pio爲PCRE,不區分大小寫,打印每行一個匹配。)

$ echo "Ben sits on a bench better end" \ 
    |grep -Pio '(?=b(?!en)|(?<!b)en|e(?!n)|(?<!be)n|[^ben])\w+' 
sits 
on 
a 
ch 
better 
end 

我基本上製造用於在「本」的任何字母,所以我可以僅包括迭代的特例它們本身並不是字符串「ben」的一部分。正如我所說,即使我在技術上回答您的問題,也不是很實際。如果您需要更多詳細信息,我還保存了a blow-by-blow explanation of this regex

如果你被迫使用純正則表達式而不是代碼,你最好的辦法就是寫代碼生成正則表達式。這樣你可以保留一個乾淨的副本。


我不知道你在問什麼對你的挑戰的剩餘部分;正則表達式要麼是貪婪的,要麼是懶惰的,我不知道任何可以找到「每一種組合」的實現,而不是任何一種方法的第一種組合。如果有這樣的事情,現實生活中會非常緩慢(而不是簡單的例子);如果他們被迫檢查每一種可能性,基本上是ReDoS,正則表達式引擎的慢速將是不能容忍的。

例子:

# greedy evaluation (default) 
$ echo 1a2be3 |grep -Pio '(?!\d[a-z]\d)\w+' 
a2be3 

# lazy evaluation 
$ echo 1a2be3 |grep -Pio '(?!\d[a-z]\d)\w+?' 
a 
2 
b 
e 
3 

我假定你正在尋找11aaa2a2ba2bea2be322b2be2be3bbebe3ee33,但我不認爲你可以得到一個純的正則表達式。你需要一些代碼來生成每個子字符串,然後你可以使用正則表達式來過濾禁止的模式(再次,這是關於貪婪vs懶惰與ReDoS)。

+0

+1謝謝你提供非常詳細的回覆,這個問題需要時間寫出來,並且不能回答這個問題還是非常有幫助的。 – Srb1313711

相關問題