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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1445506/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 02:37:03  来源:igfitidea点击:

Get content between two strings PHP

phpregexfile-get-contentsoutput-buffering

提问by Lizard

Whats is the best way to obtain the content between two strings e.g.

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

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}

For some reason this appears to work on one place in my code and not another. Am I going about this in the right way? Or is there a better way?

出于某种原因,这似乎在我的代码中的一个地方工作,而不是另一个地方。我是否以正确的方式解决这个问题?或者,还有更好的方法?

Also is output buffer the way to do this or file_get_contents?

输出缓冲区也是这样做的方式还是file_get_contents?

Thanks in advance!

提前致谢!

回答by Adam Wright

You may as well use substr and strpos for this.

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

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

You'll need to add error checking to handle the case where it doesn't FINDME.

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

回答by OIS

  • Use #instead of /so you dont have to escape them.
  • The modifiersmakes .and \salso include newlines.
  • {and }has various functionality like from n to m times in {n,m}.
  • The basic

    preg_match('#\{FINDME\}(.+)\{/FINDME\}#s',$out,$matches);
    
  • The advanced for various tags etc (styling is not so nice by the javascript).

    $delimiter = '#';
    $startTag = '{FINDME}';
    $endTag = '{/FINDME}';
    $regex = $delimiter . preg_quote($startTag, $delimiter) 
                        . '(.*?)' 
                        . preg_quote($endTag, $delimiter) 
                        . $delimiter 
                        . 's';
    preg_match($regex,$out,$matches);
    
  • 使用#而不是/这样你就不必逃避它们。
  • 修改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);
    

Put this code in a function

将此代码放入函数中

  • For any file which you do not want to execue any strayphp code, you should use file_get_contents. include/require should not even be an option there.
  • 对于您不想执行任何杂散php 代码的任何文件,您应该使用 file_get_contents。include/require 甚至不应该是那里的一个选项。

回答by Airy

I love these two solutions

我喜欢这两个解决方案

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

I also made few benchmarks as well with both solutions above and both are giving almost the same time. You can test it as well. I gave both functions a file to read which had about 60000 characters (reviewed with Ms. Word's word count) and both functions resulted in about 0.000999 seconds to find.

我还对上述两种解决方案进行了一些基准测试,并且两者几乎同时给出。你也可以测试一下。我给了两个函数一个文件来读取它有大约 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 />";

回答by Donovan P

I like to avoid using regex if possible, here is alternative solution to fetch all strings between two strings and returns an array.

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

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}}", "{{", "}}"));

Results :

结果 :

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

回答by Cem Kalyoncu

Line breaks can cause problems in RegEx, try removing or replacing them with \n before processing.

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

回答by Alex Protopopescu

This is a PHP solution that returns the strings found between tags in a haystack. It works, but I haven't tested for efficiency. I needed this and was inspired by Adam Wright's answer on this page.

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

Returns an array() containing all the strings found between $tag and $end_symbold.$tag in $haystack, or FALSE if no $end_symbol.$tag was found hence no tag pair exists in the $haystack.

返回一个包含在 $haystack 中 $tag 和 $end_symbold.$tag 之间找到的所有字符串的 array(),如果没有找到 $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;
}

回答by Ravi Verma

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

回答by Bob

Quick way to put everything into one string.

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

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