2014-03-12 10 views
0

我在this website about regular expressions上找到了一組單詞。我試了5號,並設法匹配我所需要的相反。如何否定這個正則表達式?

這些不應該匹配:

abba 
anallagmatic 
bassarisk 
... 

這些亦宜:

acritan 
aesthophysiology 
amphimictical 
... 

這種模式的逆匹配:

([a-z])([a-z])\2\1 

不幸的是,我不知道如何否定它。我讀到這個:

(?!([a-z])([a-z])\2\1) 

但似乎簡單的嵌套不起作用。使用正則表達式支持組嵌套嗎?

它可以做什麼?

+0

不要讓讀者需要參考鏈接頁面。寫出你正在處理的模式。 – sawa

+1

我做過了,不是嗎?參考只是爲了完整。 – Xiphias

+0

不,你沒有。你只是給出了列表而沒有解釋他們爲什麼匹配或不匹配 – sawa

回答

5

回答你的問題

你必須得到一點花哨的:

^((?!([a-z])([a-z])\3\2).)+$ 

Regular expression visualization

Debuggex Demo

一些提示

因爲這個來自regex golf puzzle 5 at http://regex.alf.nu/,我會給你幾個提示。

首先,對不熟悉these puzzles的讀者作一些說明:這是一個基於xkcd comic 1313的謎題。它被稱爲「正則表達式高爾夫」。給出兩個列表,並且必須弄清楚如何匹配其中一個元素中的所有元素,但是使用最短的正則表達式可以找到其中的元素。在所討論的網站上,大多數謎題在其中一個列表中有一個模式,目標是找出適用的規則,並使用該規則編寫短正則表達式,或者,如果更短,則使用正則表達式忽略規則,但恰好工作。在這種情況下,您希望匹配不在的字詞中包含abba(或itti或其他任何字符)的字詞。

提示1:這是較短的,因爲它取代[a-z]\S

^((?!(\S)(\S)\3\2).)+$ 

Regular expression visualization

Debuggex Demo

提示2:儘管兩種正則表達式以上工作,沒有任何意思是拼圖最短的工作正則表達式。最短的工作正則表達式是一種「作弊」,因爲它並不與字面匹配,但仍能正確區分列表。

+0

這很酷。我只是不明白爲什麼我們需要'?:'。我認爲它禁用了對該組的反向引用。這不正確嗎?我把它解釋爲:「匹配模式前面的任何字符('.')至少一次,如果它是真的,則由於'?!'。'」而跳過該單詞。 '^'不需要模式開始?而不是'$'要求模式最後?這是因爲'?:'這裏的不同嗎? – Xiphias

+0

你是對的;我們不需要':'。抱歉;忘了我是正規高爾夫球! :)但是,如果你取出'?:',則必須將backrefs從'\ 2 \ 1'更改爲'\ 3 \ 2',因爲最外面的'(...)'組變成了'\ 1' 。看到我上面編輯的版本。 –

3

這已經在這裏找到答案:

How to negate the whole regex?

或者另一個想法是,你可以在代碼中做到這一點。例如,在C#中..

strin gtext = "abba"; 
Regex r = new Regex("([a-z])([a-z])\2\1"); 
if(!r.IsMatch(text)) 
//Then do something 

With!你說的一樣,如果是不匹配

+1

我認爲這是最有效的方法......試圖「否定」正則表達式是很麻煩的(但並非不可能,因爲Ed Cottrell的答案試圖顯示),因爲匹配的語義是沿着「我找到了一個明確的匹配我的RE「 - 找到一個匹配到你的」否定的RE「並不一定證明在你的」正RE「沒有匹配後面的字符串。 – twalberg

+0

謝謝twalberg! –

+2

這是一個聰明的解決方案!對於測驗來說,這不適用,但在現實世界的情況下,這可能是一個優雅的解決方案。 – Xiphias