【问题标题】:Get content between two strings PHP获取两个字符串之间的内容 PHP
【发布时间】:2010-11-29 13:14:48
【问题描述】:

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

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?

提前致谢!

【问题讨论】:

  • 如果它在某些情况下有效而在其他情况下无效,您应该提供示例说明何时有效,何时无效。

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


【解决方案1】:

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

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

您需要添加错误检查来处理它没有找到 FINDME 的情况。

【讨论】:

  • 这只会找到一个匹配项。
  • @472084 是的,但您可以编写一个包装函数,在 while 循环或递归中执行此代码。这个答案是一个很好的基础。
【解决方案2】:
  • 使用# 而不是/,这样您就不必逃避它们。
  • 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);
    

将此代码放入函数中

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

【讨论】:

  • 我敢打赌 {FINDME} 只是为了说明
  • 不起作用(无输出),不知道为什么...我的 startTag:src=¦ 我的 endTag:¦
【解决方案3】:

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

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
)

【讨论】:

    【解决方案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 />";
    

    【讨论】:

    • 这很棒。可以使它找到多个匹配项吗?那么返回一个包含所有匹配项的数组?
    【解决方案5】:

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

    【讨论】:

    • 改变字符串以使正则表达式模式可以正常工作通常意味着正则表达式模式设计得不好。不要挑错字符串,挑错模式。
    【解决方案6】:

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

    返回一个 array(),其中包含在 $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;
    }
    

    【讨论】:

      【解决方案7】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-09-12
        • 1970-01-01
        • 2022-12-21
        • 2017-05-10
        • 1970-01-01
        • 1970-01-01
        • 2012-12-28
        相关资源
        最近更新 更多