2009-09-18 119 views
18

什麼是獲取兩個字符串之間內容的最佳方式,例如獲取兩個字符串之間的內容PHP

ob_start(); 
include('externalfile.html'); ## see below 
$out = ob_get_contents(); 
ob_end_clean(); 

preg_match('/{FINDME}(.|\n*)+{\/FINDME}/',$out,$matches); 
$match = $matches[0]; 

echo $match; 

## I have used .|\n* as it needs to check for new lines. Is this correct? 

## externalfile.html 

{FINDME} 
Text Here 
{/FINDME} 

由於某種原因,這似乎在我的代碼中的一個地方工作,而不是另一個地方。我以正確的方式解決這個問題嗎?或者,還有更好的方法?

也是輸出緩衝區的方式來做到這一點或file_get_contents?

在此先感謝!

+0

如果它在某些情況下有效,而不是其他情況,則應提供何時有效以及何時無效的示例。 – Welbog 2009-09-18 16:08:55

回答

35
  • 使用#而不是/所以你不必逃避它們。
  • modifiers使.\s也包含換行符。
  • {}{n,m}中具有從n到m倍的各種功能。
  • 基本

    preg_match('#\\{FINDME\\}(.+)\\{/FINDME\\}#s',$out,$matches); 
    
  • 先進的各種標籤等(造型不是很好由JavaScript)。

    $delimiter = '#'; 
    $startTag = '{FINDME}'; 
    $endTag = '{/FINDME}'; 
    $regex = $delimiter . preg_quote($startTag, $delimiter) 
            . '(.*?)' 
            . preg_quote($endTag, $delimiter) 
            . $delimiter 
            . 's'; 
    preg_match($regex,$out,$matches); 
    

將這個代碼的函數

  • 對於您不想execue任何雜散 PHP代碼,你應該使用的file_get_contents的任何文件。包括/要求甚至不應該成爲一種選擇。
+2

我打賭{FINDME}只是爲了說明 – 2009-09-18 16:14:16

39

您不妨使用substr和strpos。

$startsAt = strpos($out, "{FINDME}") + strlen("{FINDME}"); 
$endsAt = strpos($out, "{/FINDME}", $startsAt); 
$result = substr($out, $startsAt, $endsAt - $startsAt); 

您需要添加錯誤檢查以處理不FINDME的情況。

+1

這是做這件事的最佳方式,當它可能 – 2009-09-18 16:15:02

+0

同意傑姆Kalyoncu – Peter 2011-08-29 16:06:42

+0

謝謝你的替代解決方案,它解決了我的問題。我正在用一個大字符串執行一個preg_match,該字符串返回一個空數組。你的解決方案解決了我的問題 – meenxo 2013-09-20 22:47:46

1

換行符可能會導致RegEx出現問題,請在處理前嘗試刪除或替換它們。

-1

將所有內容放入一個字符串的快速方法。

$newlines = array("\t","\n","\r","\x20\x20","\0","\x0B"); 
$one_string = str_replace($newlines, "", html_entity_decode($content)); 
0
function getInbetweenStrings($start, $end, $str){ 
    $matches = array(); 
    $regex = "/$start([a-zA-Z0-9_]*)$end/"; 
    preg_match_all($regex, $str, $matches); 
    return $matches[1]; 
} 


$str = "C://@@[email protected]@/@@[email protected]@/@@[email protected]@"; 
$str_arr = getInbetweenStrings('@@', '@@', $str); 

print_r($str_arr); 
+0

這只是行不通的。例如'getInbetweenStrings('start','end','start get this string end');' – billynoah 2014-10-30 01:32:56

4

我喜歡這兩種解決方案

function GetBetween($content,$start,$end) 
{ 
    $r = explode($start, $content); 
    if (isset($r[1])){ 
     $r = explode($end, $r[1]); 
     return $r[0]; 
    } 
    return ''; 
} 


function get_string_between($string, $start, $end){ 
    $string = " ".$string; 
    $ini = strpos($string,$start); 
    if ($ini == 0) return ""; 
    $ini += strlen($start); 
    $len = strpos($string,$end,$ini) - $ini; 
    return substr($string,$ini,$len); 
} 

我也做了一些基準以及以上兩種解決方案並且都給出幾乎相同的時間。你也可以測試它。我給這兩個函數提供了一個文件來讀取,其中有大約60000個字符(用Word的字數統計),並且這兩個函數在大約0.000999秒內找到。

$startTime = microtime(true); 
GetBetween($str, '<start>', '<end>'); 
echo "Explodin Function took: ".(microtime(true) - $startTime) . " to finish<br />"; 

$startTime = microtime(true); 
get_string_between($str, '<start>', '<end>'); 
echo "Subsring Function took: ".(microtime(true) - $startTime) . " to finish<br />"; 
+0

這太好了。它可以使工作找到多個匹配?那麼返回一個包含所有匹配的數組? – 2015-05-31 04:19:35

0

這是一個PHP解決方案,它返回乾草堆中標籤之間發現的字符串。它有效,但我沒有測試效率。我需要這個,並受到了亞當賴特在本頁上的回答的啓發。

如果沒有$ end_symbol。$標籤被發現返回,因此沒有標記對在$草堆存在包含所有$標籤和$ $草堆end_symbold。$標籤,或FALSE之間發現的字符串的數組()。

function str_between_tags($haystack, $tag, $end_symbol){ 
    $c_end_tags = substr_count($haystack, $end_symbol.$tag); 
    if(!$c_end_tags) return FALSE; 

    for($i=0; $i<$c_end_tags; $i++){ 
     $p_s = strpos($haystack, $tag, (($p_e)?$p_e+strlen($end_symbol.$tag):NULL)) + strlen($tag); 
     $p_e = strpos($haystack, $end_symbol.$tag, $p_s); 
     $result[] = substr($haystack, $p_s, $p_e - $p_s); 
    } 
    return $result; 
} 
相關問題