2011-05-26 19 views
0

我有像下面這樣的URL需要被PHP代碼識別。根據網址是什麼,數據需要顯示:識別URL類型並使用正則表達式基於它執行操作

www.example.com/music/username/popular 
http://www.example.com/music/username/recent/ 
http://example.com/music/username/favorites/ignore_this /*Ignore everything after favorites*/ 
http://www.example.com/music/2011/05/02 /*Shows all music uploaded on this date*/ 
www.example.com/groups 
http://www.example.com/groups/jazz 
http://example.com/places/japan/?param=ignore_this /*Ignore everything after japan*/ 
www.example.com/search/rock/ 

第一個URL應顯示用戶的流行音樂。 www.example.com/groups應列出所有公共團體。等..

  • http://是可選
  • /末是可選
  • 如果有什麼(如groups)以大寫輸入,應該轉換成小寫

什麼是識別這些URL的最佳方式,使用正則表達式並創建Switch大小寫?示例代碼片段會很棒。

回答

0

這裏是我使用的系統(它是面向對象,但如果你不喜歡類,你可以很容易地改變)。

if($this->request->uriMatch('#^/$#')) //simplest regexp, no substring is matched 
    $this->home(); //show the Home page 
elseif($this->request->uriMatch('#^/news/(\d+)\.html$#')) //matches a number! 
    $this->newsItem($this->request->uri(0),0); // calls newsItem() function and passes the first (0th) matched substring (in our case it's number) to it as an argument 
elseif($this->request->uriMatch('#^/news_(\d{4})_(\d{1,2})\.html$#')) //matches 2 numbers 
    $this->newsList(0,$this->request->uri(0),$this->request->uri(1)); //passes both numbers to function newsList() 
elseif($this->request->uriMatch('#^/products/latest(?:-(\d+))?\.html$#')) //may match one number, or may not match anything 
    $this->products('latest',$this->request->uri(0,1)); //if matched, passes the matched number, if not: passes "1" (as default value) 
elseif($this->request->uriMatch('#^/products/(\d+)(?:-(\d+))?\.html$#')) //may match 1 or 2 numbers, this is a mix of previous 2 cases :) 
    $this->products($this->request->uri(0),$this->request->uri(1,1)); 
else //if nothing was matched, then 404! 
    $this->response->redirect('/404.html'); 

注意(?:)正則表達式是不匹配的子模式,因此它不會造成任何影響。您的情況

一個例子您提供:

if($this->request->uriMatch('#^/music/([a-z0-9]+)/favorites/?#i')) 

?意味着最後一個/可能不存在。請注意,最後沒有$符號,這意味着favorites之後的所有內容都將被忽略。 i修飾符(在#之後)表示文本大小寫不重要。

$this->requestclass Request一個實例,那就是:

class Request{ 
    private $uri; //this holds the URI 
    private $uriArray; //this will hold the matched substrings of the URI according to our REGEXPs 
    public function __construct(){ 
     // initializes URI, it doesn't contain http:// and the domain! 
     $this->uri = $_SERVER['REQUEST_URI']; 
    } 
    public function uriMatch($regex){ 
     // parses URL according to REGEX 
     $b = preg_match($regex, $this->uri, $this->uriArray); // $b is false, if the URL was not matched 
     if($b==1) //if $b is not false, uriArray contains the URL AND the matched substrings (http://am.php.net/manual/en/function.preg-match.php). 
      array_shift($this->uriArray); // we are removing the first element (which is the URL), we need only matched substrings 

     return $b==1; //returns true if and only if the URL was matched! 
    } 

    public function uri($n, $default=false){ 
     //returns n-th matched substring, or $default, if it was not set 
     // ... one can add some error handling here 
     return isset($this->uriArray[$n]) ? $this->uriArray[$n] : $default; 
    } 
} 
0

使用通用的URL正則表達式來查找它們,並使用preg_replace_callback()來調用回調函數,該函數使用parse_url()來提取您需要的部分。

不要試圖在一個正則表達式中做太多。

0

這是正則表達式,我會用:

preg_match('%(?:www)?.example.com/(\w+)/?(\w+)?/?(\w+)?/?(\w+)?%i',$matchee)

可以比測試matchee實際匹配或不併建立不同的情況:ignore_this或日期部分。 strtolower($matchee[1])將包含小寫域後的第一個元素,等等...

注意:我建議使用RegexBuddy作爲工具來調試您的正則表達式查詢。我經常做。