2012-04-01 37 views
2

我需要一個正則表達式來返回路徑中的最後一個目錄。如何使用Zeus重寫規則從URL路徑獲取最後一個目錄?

例如從www.domain.com/shop/widgets/返回「小部件」。

我有一個幾乎可以工作的表達式。

[^/].*/([^/]+)/?$ 

它會返回「小部件」,從www.domain.com/shop/widgets/而不是從www.domain.com/widgets/

我還需要忽略包括文件名的網址。所以那www.domain.com/shop/widgets/blue_widget.html將不匹配。

這必須使用正則表達式來完成,因爲它是用於Zeus服務器請求重寫模塊的。

+0

你定義爲「文件名」是什麼? – Amber 2012-04-01 07:05:26

+0

'$ what_i_want =(split「/」,$ url)[ - 1]'也會給你答案。 – Unos 2012-04-01 07:32:48

+3

@freespace您是否閱讀過OP的文章? 「這必須使用perl正則表達式來完成,就像Zeus服務器請求重寫模塊一樣。」 – Amber 2012-04-01 17:24:41

回答

1

這通常應該工作:

/([^/.]+)/$ 

它必須以斜線結束的字符串,第二個到最後斜線後一組的非斜線,非週期字符匹配。

「文件夾名稱」將位於第一個捕獲組中。

+6

怎麼樣'http://www.example.com/hier/archy?f = 1&y = zz/qq#frag/ment'?這裏的最後一個「文件夾」可能是'archy'。或者'qq'甚至'ment',這取決於URL的使用方式。 – 2012-04-01 07:31:51

+2

@JamesYoungman [a] OP的網址似乎在使用尾部斜槓。 [b]服務器級別的大多數URL重寫引擎(OP詢問的內容)不包括查詢字符串,並且服務器永遠不會看到該片段。 [c]如果他們真的希望結尾的斜線是可選的,他們可以在模式中的最後一個'/'之後加一個'?'。 – Amber 2012-04-01 17:21:51

+0

(還有一個事實,幾乎所有其他的upvoted答案在這裏做同樣的事情,其中​​大多數效率較低。不知道爲什麼所有反對這個具體。) – Amber 2012-04-01 17:26:15

1
#!/usr/bin/perl 

use strict; 
use warnings; 

$_ = 'www.domain.com/shop/widgets/'; 
print "$1\n" if (/\/([^\/]+)\/$/); 

$_ = 'www.domain.com/shop/widgets/blue_widget.html'; 
print "$1\n" if (/\/([^\/]+)\/$/);' 
+0

這實際上適用於OP提供的所有案例(即www.domain.com/shop/widgets/blue_widget.html和www.domain.com/shop/widgets/)。 – BluesRockAddict 2012-04-02 00:22:14

+0

@BluesRockAddict除OP要它不匹配以文件名結尾的URL - 不匹配它們並返回文件夾。 *「我還需要忽略任何包含文件名的網址」* – Amber 2012-04-02 00:40:42

2
/^www\.example\.com\/([^\/]+\/)*([^\/]+)\/$/ 

這是什麼呢?

  • 匹配該域的普通文本。根據需要進行調整。
  • 匹配任意數目的目錄,每個目錄由非斜槓字符和斜槓組成。
  • 匹配一串非斜線。
  • 匹配輸入末尾的斜槓,從而消除文件(因爲只有目錄以斜線結尾)。

實現在Perl:

[[email protected] ~] cat perltest 
#!/usr/local/bin/perl 

@test = (
     'www.example.com/path/to/file.html', 
     'www.example.com/match/', 
     'www.example.com/pages/match/', 
     'www.example.com/pages/widgets/thingy/', 
     'www.example.com/foo/bar/baz/', 
); 

foreach (@test) { 
     $_ =~ m/^www\.example\.com\/([^\/]+\/)*([^\/]+)\/$/i; 
     printf(">> %-50s\t%s\n", $_, $2); 
} 

[[email protected] ~] ./perltest 
>> www.example.com/path/to/file.html      
>> www.example.com/match/        match 
>> www.example.com/pages/match/       match 
>> www.example.com/pages/widgets/thingy/    thingy 
>> www.example.com/foo/bar/baz/       baz 
[[email protected] ~] 
+0

我沒有低估這一點,但它似乎不適用於www.domain.com/shop/widgets/blue_widget.html案例。 – BluesRockAddict 2012-04-02 00:21:24

+0

適合我。當我包含'blue_widget.html'這一行時,它的處理方式與我的'file.html'示例相同 - 也就是說'$ 2'仍未設置。你是怎麼測試的? – ghoti 2012-04-02 01:35:48

+0

對不起ghoti,我誤解了原來的問題。你的回答是正確的。 – BluesRockAddict 2012-04-02 04:14:53

0

你不想一個Perl的正則表達式。你想要一個Zeus會理解的正則表達式。雖然他們可能會調用PCRE,但即使PCRE也不能處理所有的Perl正則表達式。

這裏的大部分答案都是錯誤的,因爲他們沒有考慮可以作爲輸入獲取的不同種類的URL。

  • 得到公正的URL
  • 對陣路徑部分的路徑部分找到你所需要的
  • ,在文件名結尾的路徑和那些不

區分有一些例子可以用作開始。我不使用宙斯與不想,所以接下來的部分是由你:

我已經請閱讀,您可以通過Perl Extensions for ZWS將請求傳遞給Perl程序,但如果需要這樣做,我會感到很驚訝。如果你不得不求助於此,我會使用URI模塊解析URI並提取路徑。一旦你的,分裂的道路變成它的組成部分:

一旦你這一步,你必須決定要如何識別象目錄。如果您直接映射到文件系統結構,那麼只需在@parts之前彈出元素,直到找到目錄爲止,然後計算要跳過的數字。

但是,無論我放在Perl程序中,我都會畏縮這樣做。我會努力讓它首先在宙斯規則中完成。向我們展示你到目前爲止所擁有的。