2012-04-07 61 views
5

我有這種模式編寫與某些擴展名不匹配的正則表達式模式?

^.*\.(?!jpg$|png$).+$ 

但是有一個問題 - 這個模式匹配file.name.jpg(2點)

它的工作原理上正確filename.jpg(不匹配)。我試圖弄清楚如何使它不匹配任何.jpg文件,即使文件名稱中有2個或更多點。我試圖用後面的一個看,但蟒蛇抱怨不使用固定寬度(我不完全確定是什麼意思,但文件名將是可變長度。)

回答

10

這應該工作:^.*\.(?!jpg$|png$)[^.]+$

+0

偉大的工作!優秀 – yash 2017-03-16 18:23:56

3

使用os.path的俏皮功能來正確拆分了文件路徑爲組件用來分析:

filepath, filename = os.path.split(str) 
basename, extension = os.path.splitext(filename) 

if exension[1:] in ['jpg', 'png']: 
    # The extension matches 

試試這個正則表達式(不這樣做,它做你想做的事完全相反。):

\.(jpg|png)([^\.]|$) 
+0

我沒有訪問Python的東西,它是Python的正則表達式引擎,但我只能訪問JSON配置文件以將正則表達式放到Python程序中。我刪除了Python標籤以防止混淆。 – 2012-04-07 05:33:50

+0

看我的編輯。我認爲它應該可以工作 – Blender 2012-04-07 05:50:09

+0

你的正則表達式看起來像試圖排除包含* .jpg或'.png.'的字符串,但我相信這個想法是用'.jpg'排除任何*結尾的東西或'.png'。 OP的正則表達式失敗了,因爲lookahead和最終的'。+ $'都可以在'file.name.jpg'中的第一個'.'之後匹配。正如@bereal所做的那樣,將它改爲'[^。] + $',強制前視僅應用於最終點 - 無論什麼順序。 – 2012-04-07 08:28:29

0

請嘗試

 
    .*\.(jpg$|png$) 

它將正確匹配filename.jpg。你試圖找出如何匹配任何.jpg文件,即使該文件的名稱有2個或更多的點,它將工作正常。
使用python腳本時,請確保您使用的是正確類型的分割。 不同類型的拆分即rsplit(右分割)和lsplit(左分割)。

+0

你已經得到它:正則表達式不應該匹配'filename.jpg'或'file.name.png'。我猜想,'filename.txt'或'file.name.foo'都可以。 – 2012-04-07 07:57:36

1

看起來你幾乎擁有了:

.*\.(?!jpg$|png$)[^.]+ 

根據我的測試(在Java中)我得到這些結果:

file.jpg - false 
file.png - false 
file.name.jpg - false 
file.name.png - false 
file.gif - true 
file.name.gif - true 
file.jpg.gif - true 
file.jpge - true 

如果這不是你想要的請求更新你的問題是什麼你的期望。

1

如果你只關心字符串不與.jpg.png結束,您可以使用此:

^.+$(?<!\.jpg)(?<!\.png) 

^.+並非絕對必要,但根據JSON解析器是如何編碼的你可能需要強制正則表達式消耗整個字符串。如果您使用其他驗證正則表達式,以及,你可能想要的東西更復雜,如:

^\w+(?:\.\w+)+$(?<!\.jpg)(?<!\.png) 

你可能嘗試使用(?<!\.jpg|\.png),這是行不通的,因爲Python的正則表達式的味道是一個最當涉及到向後看時,這是限制性的。 PHP和Ruby 1.9+會接受它,因爲每個選項都有固定的長度。他們甚至不必是長度相同的長度; (?<!\.jpg|\.jpeg|\.png)也可以工作。只是不要嘗試分解點,如(?<!\.(?:jpg|jpeg|png));交替必須在逆序的頂層。

Java會接受因式分解版本,因爲它在編譯時會做更多的工作來確定lookbehind可能需要匹配的最大字符數。後視表達式雖然需要相當簡單,但它不能使用量化符+*。最後,.NET和JGSoft的風格在lookbehinds上沒有任何限制。但是Python做了一個非常簡單的嘗試,想弄清楚lookbehind需要匹配的字符的確切數量,當它失敗時產生那個神祕的錯誤信息。

+0

謝謝,很好的答案。 – 2012-04-07 22:30:14