2011-12-22 29 views
2

我在寫路由類,需要幫助。我需要解析$ controller變量並將該字符串的一部分分配給另一個變量。這裏是$控制器的例子:解析字符串 - 與正則表達式或類似的東西?

$controller = "admin/package/AdminClass::display" 
//$path = "admin/package"; 
//$class = "AdminClass"; 
//$method = "display"; 

$controller = "AdminClass::display"; 
//$path = ""; 
//$class = "AdminClass"; 
//$method = "display"; 

$controller = "display" 
//$path = ""; 
//$class = ""; 
//$method = "display"; 

這三種情況是我所需要的。是的,我可以寫很長的程序來處理這種情況,但我需要的是用正則表達式簡單的解決方案,具有功能preg_match_all

任何建議如何做到這一點?

+0

請在您關於其他解析情況/您可能需要解析的其他字符串的問題中更具體。第一個到第二個值可以通過replace/substring/split完成。 – Smamatti 2011-12-22 20:30:42

+1

爲什麼你需要使用正則表達式? – CanSpice 2011-12-22 20:37:20

+0

@CanSpice,匹配這三種情況,然後將字符串的部分提取到變量 – sasa 2011-12-22 20:40:30

回答

5

以下正則表達式應該爲您完成此操作,然後您可以將捕獲的組保存到$path,$class$method

(?:(.+)/)?(?:(.+)::)?(.+) 

這裏是一個Rubular:

你的PHP代碼可能是這個樣子:

$regex = '/(?:(.+)\/)?(?:(.+)::)?(.+)/'; 
preg_match($regex, $controller, $matches); 
$path = $matches[1]; 
$class = $matches[2]; 
$method = $matches[3]; 
+0

謝謝!如果你有任何鏈接,我可以輕鬆地學習正則表達式,我將非常感謝:) – sasa 2011-12-22 20:45:49

+1

我使用http://www.regular-expressions.info/reference.html作爲備忘單,並且該網站有一些很好的教程。 Rubular對於快速測試你的正則表達式也非常有用。 – 2011-12-22 20:48:46

+1

這也會匹配'a/b',這不是合法的輸入! – fge 2011-12-22 20:54:04

-1
 $pieces = explode('/',$controller); 
     $path = ''; 
     for($i = $i<$pieces.length-1; $i++) 
     { 
      if($i != 0) 
      $path+='/'; 
      $path += $pieces[$i]; 
     } 
     $p2 = explode( '::',$pieces[$pieces.length-1]); 
     $class = $p2[0]; 
     $method = $p2[1]; 
3

這個假設的類和方法名稱中的路徑,只能包含字母。

完整的正則表達式如下:

^(?:((?:[a-zA-Z]+/)*)([a-zA-Z]+)::)?([a-zA-Z]+)$ 

兩個非捕獲基團:可避免不同的路徑元素的捕獲的第一個,這使得所有路徑和類可選的,第二個。

說明:

  • 路徑元素是一個或多個字母,接着一個/:[a-zA-Z]+/;
  • 有可能是零個或更多的人:我們必須將*量詞以上;但正則表達式不是原子,因此我們需要一個組。由於我們不想捕獲單個路徑元素,因此我們使用非捕獲組:(?:[a-zA-Z]+/)*;
  • 我們想捕捉的完整路徑,如果它的存在,我們必須使用一個捕獲組在這個((?:[a-zA-Z]+/)*);
  • 方法名稱是一個或多個字母,我們要捕獲它:([a-zA-Z]+);
  • 如果存在的話,它遵循的路徑,之後是兩個分號:((?:[a-zA-Z]+/)*)([a-zA-Z]+)::;
  • ,但是這一切都是可選的。所以,我們必須把一組圍繞這一切,這再一次,我們不希望捕捉到:(?:((?:[a-zA-Z]+/)*)([a-zA-Z]+)::)?;
  • 最後,接着是方法的名稱,這是不可選的這段時間,和我們想捕捉:(?:((?:[a-zA-Z]+/)*)([a-zA-Z]+)::)?([a-zA-Z]+);
  • ,我們希望這對整條生產線相匹配:我們需要的在開始和結尾,這給最後的結果來錨定它既:^(?:((?:[a-zA-Z]+/)*)([a-zA-Z]+)::)?([a-zA-Z]+)$

唷。

+0

第二個正則表達式返回具有方法AdminClass :: display的類。我認爲由FJ的正則表達式可以作爲第二個 – sasa 2011-12-22 21:12:42

+0

嗯,它確實可以用一個正則表達式完成,沒有錯誤,但它將是一個非常長的正則表達式,需要更多的解釋;)我可以做它並解釋所有如果你想。 – fge 2011-12-22 21:18:43

+0

這不會匹配'a/b'並將其全部放入'$ method'中? – 2011-12-22 21:23:17