获取两个字符串PHP之间的内容

时间:2009-09-18 16:06:49

标签: php regex file-get-contents output-buffering

什么是获取两个字符串之间内容的最佳方式,例如

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?

提前致谢!

8 个答案:

答案 0 :(得分:41)

你也可以使用substr和strpos。

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

您需要添加错误检查以处理它不是FINDME的情况。

答案 1 :(得分:39)

  • 使用#代替/,这样您就不必逃避它们。
  • modifier s使.\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);
    

将此代码放入函数

  • 对于您不想使用任何 stray php代码执行的任何文件,您应该使用file_get_contents。 include / require甚至不应该是一个选项。

答案 2 :(得分: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 />";

答案 3 :(得分:1)

换行符可能会导致RegEx出现问题,尝试在处理之前用\ n删除或替换它们。

答案 4 :(得分:1)

如果可能的话,我想避免使用正则表达式,这是另一种解决方案,可提取两个字符串之间的所有字符串并返回一个数组。

function getBetween($content, $start, $end) {
    $n = explode($start, $content);
    $result = Array();
    foreach ($n as $val) {
        $pos = strpos($val, $end);
        if ($pos !== false) {
            $result[] = substr($val, 0, $pos);
        }
    }
    return $result;
}
print_r(getBetween("The quick brown {{fox}} jumps over the lazy {{dog}}", "{{", "}}"));

结果:

Array
(
    [0] => fox
    [1] => dog
)

答案 5 :(得分: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://@@ad_custom_attr1@@/@@upn@@/@@samaccountname@@";
$str_arr = getInbetweenStrings('@@', '@@', $str);

print_r($str_arr);

答案 6 :(得分:0)

这是一个PHP解决方案,它返回在大海捞针中的标记之间找到的字符串。它有效,但我还没有测试效率。我需要这个,并且受到Adam Wright在本页面上的回答的启发。

返回一个array(),其中包含$ tag和$ end_symbold之间找到的所有字符串。$ hashstack中的$ tag,如果没有找到$ end_symbol。$ tag则返回FALSE,因此$ haystack中不存在任何标记对。

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;
}

答案 7 :(得分:-1)

快速将所有内容放入一个字符串中。

$newlines = array("\t","\n","\r","\x20\x20","\0","\x0B");
$one_string = str_replace($newlines, "", html_entity_decode($content));