2009-09-18 32 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; 
} 
相关问题