2010-09-15 16 views
1

我需要幫助Reg。防爆。我有一個很長的文本與許多空格和新行,我需要找到並選擇2個字符串之間的所有。 例如:正則表達式幫助(PHP)查找和選擇2個字符串之間的字符

iojge test rgej <foo> 
ferfe 098n34hjlrej 
fefe <end 

我想找到所有的測試和結束之間:

rgej <foo> 
ferfe 098n34hjlrej 
fefe < 

我怎麼能做到這一點?

+0

所以,' test'和'end'永遠不會成爲你想要匹配的文本的一部分?如果字符串看起來像:''測試測試結束結束符''? – 2010-09-15 18:18:19

回答

4

您可以嘗試

preg_match("/test(.*?)end/s", $yourString, $matches); 
print_r($matches); 
+0

'm'標誌將導致'$'匹配行的末尾,'^'匹配行的開始:它將*不*讓DOT元字符匹配換行符。這是用's'標誌完成的。 – 2010-09-15 18:16:54

+0

@巴特K.哎呀,你是對的。 – 2010-09-15 18:18:58

+0

一個經典的錯誤。 :) – 2010-09-15 18:20:22

2

您可以使用兩種lookarounds/s(單線)modifier,這使得dot匹配換行符,尋找一切你兩個單詞之間:

/(?<=test).*(?=end)/s 

爲了解釋:

(?<= # open a positive lookbehind 
    test # match 'test' 
)  # close the lookbehind 
.*  # match as many characters as possible (including newlines because of the \s modifier) 
(?=  # open a positive lookahead 
end # match 'end' 
)  # close the lookahead 

這些變換可以讓你斷言模式必須以你的兩個單詞爲基礎,但由於lookarounds沒有捕獲,只有單詞之間的所有內容都會由返回。在後面看當前位置看看斷言是否通過;一看就是之後的當前位置。

由於默認情況下正則表達式爲greedy,所以.*將盡可能地匹配(因此,如果結束詞出現多次,它將匹配到最後一次)。如果你想只匹配第一次遇到end直到,你可以使.*lazy,改成.*?(換句話說,它會匹配爲儘可能仍然滿足模式)(即/(?<=test).*?(?=end)/s )。

+0

爲了安全起見,我會讓它變成一個不願意的DOT-STAR。 – 2010-09-15 18:19:56

+0

@取決於OP想要捕獲什麼。儘管我已經更新了我的答案來討論這個問題。 – 2010-09-15 18:20:38

0

如果你有固定的分隔符,你不需要正則表達式:

$str = 'iojge test rgej <foo> 
ferfe 098n34hjlrej 
fefe <end'; 
$start = 'test'; 
$end = 'end'; 
if (($startPos = strpos($str, $start)) !== false && ($endPos = strpos($str, $end, $startPos+=strlen($start))) !== false) { 
    // match found 
    $match = substr($str, $startPos, $endPos-$startPos); 
} 
1

或者你也可以這樣做:

$arr1 = explode("test",$input); 
$arr2 = explode("end",$arr1[1]); 
$result = $arr2[0]; 
+1

如果'$ input'中沒有'test'會怎麼樣? – Gumbo 2010-09-15 18:30:52

+0

@Gumbo:在這種情況下,'$ result'將是空字符串。但我認爲會有一些無效索引的警告。所以你是對的,需要進行一些錯誤檢查。 – codaddict 2010-09-15 18:49:20

相關問題