2017-04-25 97 views
1

php的正則表達式我有例如以下字符串獲取字符串

@kirbypanganja [柯比Panganja] elow @kyraminerva [凱拉]測試@watever [watever永遠常青]

我想得到與@username [Full Name]匹配的子字符串,我真的是新的正則表達式的東西。我使用的是ff代碼:

$mention_regex = '/@([A-Za-z0-9_]+)/i'; 
preg_match_all($mention_regex, $content, $matches); 
var_dump($matches); 

其中$ content是上面的字符串。 什麼應該是正確的正則表達式,以便我可以有陣列@用戶名[全名]格式?

+0

所以,你只是想匹配方括號之間的所有值?因爲沒有辦法知道這是否是一個名字 – Jerodev

+0

爲什麼不簡單'''$ array = explode('@',$ yourstring);'那麼你有'array('kirbypanganja [Kirby Panganja] elow','kyraminerva [Kyra ] test','....');' – JustOnUnderMillions

回答

0

正則表達式:/@[A-Za-z0-9_]+\[[a-zA-Z\s]+\]/

/@[A-Za-z0-9_]+\[[a-zA-Z\s]+\]/這將匹配

實施例:@thanSomeCharacters[Some Name Can contain space]

Try this code snippet here

<?php 
$content='@kirbypanganja[Kirby Panganja] elow @kyraminerva[Kyra] test @watever[watever ever evergreen]'; 
$mention_regex = '/@[A-Za-z0-9_]+\[[a-zA-Z\s]+\]/i'; 
preg_match_all($mention_regex, $content, $matches); 
print_r($matches); 
1

您可以使用:

@[^]]+] 

即:

$string = "@kirbypanganja[Kirby Panganja] elow @kyraminerva[Kyra] test @watever[watever ever evergreen]"; 
preg_match_all('/@[^]]+]/', $string, $result); 
print_r($result[0]); 

輸出

Array 
(
    [0] => @kirbypanganja[Kirby Panganja] 
    [1] => @kyraminerva[Kyra] 
    [2] => @watever[watever ever evergreen] 
) 

PHP Demo

Regex Demo and Explanation

0

我會非常直接的,只有一行的方法,我認爲這是最好的,然後再討論其他選項啓動...

碼(Demo):

$string = "@kirbypanganja[Kirby Panganja] elow @kyraminerva[Kyra] test @watever[watever ever evergreen]"; 

$result=preg_split('/(?<=\]) [^@]+ /',$string,null,PREG_SPLIT_NO_EMPTY); 

var_export($result); 

輸出:

array (
    0 => '@kirbypanganja[Kirby Panganja]', 
    1 => '@kyraminerva[Kyra]', 
    2 => '@watever[watever ever evergreen]', 
) 

模式(Demo):

(?<=\]) #only match what immediately follows a closing square bracket 
[^@]+  #match a space, 1 or more non-at-signs, then a space 

我的模式需要20個步驟,這是頁面上一個很輕微的季軍。然而,我會爭辯說,因爲對用戶不會有明顯的影響,所以偏好標準轉移到編碼器的可用性上。

有兩個好處編碼器使用preg_split()

  1. 它不會返回真/假,也不需要像preg_match_all()輸出變量,這意味着它可以作爲一個班輪沒有條件語句。
  2. 它返回一維數組,而不是像preg_match_all()這樣的二維數組。這意味着整個返回的數組可以立即準備解包而不需要任何子數組訪問。

如果你想知道什麼的第三和第四參數是preg_split()null值表示返回的子無限量的。這是默認行爲,但它用作參數4的佔位符。PREG_SPLIT_NO_EMPTY可以有效地除去嘗試在輸入字符串的開頭或結尾處分割時產生的空子字符串。


以上是我推薦的方法,現在我要花點時間目前發佈此頁面上的其他答案比較,然後提出一些我不推薦使用非正則表達式的方法。

最流行和直觀的方法是使用preg_match_all()的正則表達式模式。 Sahil和Pedro都選擇了這一行動。讓我們比較一下,他們所選擇的模式...

薩赫勒的模式/@[A-Za-z0-9_]+\[[a-zA-Z\s]+\]/i正確匹配18步所需的子串,但使用不必要的重複就像使用i改性劑/標誌儘管在字符類使用A-Za-z。這是一個demo

佩德羅的圖案/@[^]]+]/在12個步驟中正確匹配所需的字符串。這是一個demo

通過所有的比較,Pedro的方法優於Sahil's,因爲它具有相同的準確性,更高的效率和更高的模式簡潔性。如果你想使用preg_match_all(),你不會找到比佩德羅更精緻的正則表達式模式。

也就是說,還有其他的方法來提取所需的子串。首先,比較繁瑣的方式,不涉及正則表達式,我永遠不會建議...

免費正則表達式法:strpos() & substr()

$result=[]; 
while(($start=strpos($string,'@'))!==false){ 
    $result[]=substr($string,$start,($stop=strpos($string,']')+1)-$start); 
    $string=substr($string,$stop); 
} 
var_export($result); 

編碼員要經常招待非正則表達式的想法方法解析字符串時,但從上面的代碼中可以看出,對於這種情況只是不明智的。它在每次迭代中需要四次函數調用,並且它不是最容易閱讀的。所以讓我們解僱這個方法。

這裏是提供正確的結果的另一種方式......

$result=[]; 
foreach(explode('@',$string) as $v){ 
    if($v){ 
     $result[]='@'.substr($v,0,strrpos($v,']')+1); 
    } 
} 

它相比之前的自由正則表達式,方法,使較少的函數調用,但它仍然過多處理這樣一個簡單的任務。

在這一點上,很明顯,最明智的方法應該使用正則表達式。並且選擇preg_match_all()沒有問題 - 如果這是我的項目,我可以選擇使用它。但是,重要的是要考慮preg_split()的直接性。此功能與explode()類似,但可以使用正則表達式。這個問題對於preg_split()是一個完美的階段,因爲應該省略的子字符串也可以用作所需子字符串之間的分隔符。