29

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

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?

提前致谢!

4

7 回答 7

49

您也可以为此使用 substr 和 strpos 。

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

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

于 2009-09-18T16:10:15.813 回答
47
  • 使用#而不是/这样你就不必逃避它们。
  • 修饰符 使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);
    

将此代码放入函数中

  • 对于您不想执行任何杂散php 代码的任何文件,您应该使用 file_get_contents。include/require 甚至不应该是一个选项。
于 2009-09-18T16:11:14.203 回答
7

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

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
)
于 2018-07-11T03:33:45.113 回答
5

我喜欢这两种解决方案

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 />";
于 2014-02-15T22:30:22.820 回答
1

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

于 2009-09-18T16:12:01.207 回答
0

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

返回一个数组(),其中包含在 $haystack 中 $tag 和 $end_symbold.$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;
}
于 2016-12-18T16:00:32.017 回答
-1

将所有内容放入一个字符串的快速方法。

$newlines = array("\t","\n","\r","\x20\x20","\0","\x0B");
$one_string = str_replace($newlines, "", html_entity_decode($content));
于 2012-12-17T23:25:07.420 回答