Как получить подстроку между двумя строками в PHP?

Мне нужна функция, которая возвращает подстроку между двумя словами (или двумя символами). Мне интересно, есть ли функция PHP, которая достигает этого. Я не хочу думать о регулярных выражениях (ну, я мог бы сделать один, но на самом деле не думаю, что это лучший путь). Думая о strpos и substr функций. Вот пример:

$string = "foo I wanna a cake foo";

Мы вызываем функцию: $substring = getInnerSubstring($string,"foo");
Возвращается: «Я хочу торт».

Заранее спасибо.

Обновление: Ну, до сих пор, я могу просто получить подстроку из двух слов в одной строке, вы позволите мне пойти немного дальше и спросить, могу ли я расширить использование getInnerSubstring($str,$delim), чтобы получить строки между значением delim, например :

$string =" foo I like php foo, but foo I also like asp foo, foo I feel hero  foo";

Я получаю массив, как {"I like php", "I also like asp", "I feel hero"}.

вопрос задан 17.04.2011
Nadjib Mami
2121 репутация

30 ответов


  • 232 рейтинг

    Если строки разные (то есть: [foo] & amp; [/ foo]), взгляните на этот пост от Джастина Кука. Я копирую его код ниже:

    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);
    }
    
    $fullstring = 'this is my [tag]dog[/tag]';
    $parsed = get_string_between($fullstring, '[tag]', '[/tag]');
    
    echo $parsed; // (result = dog)
    
    ответ дан Alejandro García Iglesias, с репутацией 13040, 22.03.2012
  • 39 рейтинг

    Регулярные выражения - это путь:

    $str = 'before-str-after';
    if (preg_match('/before-(.*?)-after/', $str, $match) == 1) {
        echo $match[1];
    }
    

    onlinePhp

    ответ дан nbrogi, с репутацией 591, 12.06.2014
  • 22 рейтинг
    function getBetween($string, $start = "", $end = ""){
        if (strpos($string, $start)) { // required if $start not exist in $string
            $startCharCount = strpos($string, $start) + strlen($start);
            $firstSubStr = substr($string, $startCharCount, strlen($string));
            $endCharCount = strpos($firstSubStr, $end);
            if ($endCharCount == 0) {
                $endCharCount = strlen($firstSubStr);
            }
            return substr($firstSubStr, 0, $endCharCount);
        } else {
            return '';
        }
    }
    

    Пример использования:

    echo getBetween("a","c","abc"); // returns: 'b'
    
    echo getBetween("h","o","hello"); // returns: 'ell'
    
    echo getBetween("a","r","World"); // returns: ''
    
    ответ дан daniel, с репутацией 229, 21.02.2013
  • 12 рейтинг
    function getInnerSubstring($string,$delim){
        // "foo a foo" becomes: array(""," a ","")
        $string = explode($delim, $string, 3); // also, we only need 2 items at most
        // we check whether the 2nd is set and return it, otherwise we return an empty string
        return isset($string[1]) ? $string[1] : '';
    }
    

    Пример использования:

    var_dump(getInnerSubstring('foo Hello world foo','foo'));
    // prints: string(13) " Hello world "
    

    Если вы хотите удалить окружающие пробелы, используйте trim. Пример:

    var_dump(trim(getInnerSubstring('foo Hello world foo','foo')));
    // prints: string(11) "Hello world"
    
    ответ дан Christian, с репутацией 20435, 17.04.2011
  • 11 рейтинг
    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);
    
    ответ дан Ravi Verma, с репутацией 201, 26.02.2013
  • 6 рейтинг

    Если вы используете foo в качестве разделителя, тогда посмотрите на explode()

    ответ дан oblig, с репутацией 1321, 17.04.2011
  • 5 рейтинг

    Мне нравятся решения с регулярными выражениями, но ни одно из них мне не подходит.

    Если вы знаете, что будет только 1 результат, вы можете использовать следующее:

    $between = preg_replace('/(.*)BEFORE(.*)AFTER(.*)/sm', '\2', $string);
    

    Измените ДО и ПОСЛЕ до нужных разделителей.

    Также имейте в виду, что эта функция вернет всю строку, если ничего не найдено.

    Это решение является многострочным, но вы можете играть с модификаторами в зависимости от ваших потребностей.

    ответ дан ragnar, с репутацией 933, 3.09.2015
  • 4 рейтинг
    
    

    Пример:

    
    

    Это вернет "парень посередине".

    ответ дан user1366605, с репутацией 46, 26.03.2015
  • 4 рейтинг

    использовать функцию strstr php дважды.

    $value = "This is a great day to be alive";
    $value = strstr($value, "is"); //gets all text from needle on
    $value = strstr($value, "be", true); //gets all text before needle
    echo $value;
    

    выходов: "is a great day to"

    ответ дан Bryce, с репутацией 417, 13.06.2017
  • 3 рейтинг

    Если у вас есть несколько повторений из одной строки, и у вас разные шаблоны [start] и [\ end]. Вот функция, которая выводит массив.

    function get_string_between($string, $start, $end){
        $split_string       = explode($end,$string);
        foreach($split_string as $data) {
             $str_pos       = strpos($data,$start);
             $last_pos      = strlen($data);
             $capture_len   = $last_pos - $str_pos;
             $return[]      = substr($data,$str_pos+1,$capture_len);
        }
        return $return;
    }
    
    ответ дан noelthegreat, с репутацией 31, 27.10.2014
  • 2 рейтинг

    Вот функция

    function getInnerSubstring($string, $boundstring, $trimit=false) {
        $res = false;
        $bstart = strpos($string, $boundstring);
        if ($bstart >= 0) {
            $bend = strrpos($string, $boundstring);
            if ($bend >= 0 && $bend > $bstart)
                $res = substr($string, $bstart+strlen($boundstring), $bend-$bstart-strlen($boundstring));
        }
        return $trimit ? trim($res) : $res;
    }
    

    Используйте его как

    $string = "foo I wanna a cake foo";
    $substring = getInnerSubstring($string, "foo");
    
    echo $substring;
    

    Вывод (обратите внимание, что он возвращает пробелы впереди и в и вашей строки, если существует)

    Я хочу торт

    Если вы хотите обрезать результат, используйте функцию как

    $substring = getInnerSubstring($string, "foo", true);
    

    Результат : Эта функция вернет false , если $boundstring не был найден в $string или если $boundstring существует только один раз в $string, в противном случае он возвращает подстроку между первым и последним вхождением $boundstring в 51620600.


    Список литературы
    ответ дан Wh1T3h4Ck5, с репутацией 6650, 17.04.2011
  • 1 рейтинг

    Я использую

    if (count(explode("", $input))>1){
          $content = explode("",explode("", $input)[1])[0];
    }else{
          $content = "";
    }
    

    Подзаголовок & lt; TAG & gt; для любого разделителя вы хотите.

    ответ дан Ángel R.G., с репутацией 11, 25.04.2018
  • 1 рейтинг

    Использование:

    
    
    ответ дан Salim, с репутацией 10399, 8.09.2013
  • 1 рейтинг

    Не профессионал php. но я недавно столкнулся с этой стеной, и это то, что я придумал.

    function tag_contents($string, $tag_open, $tag_close){
       foreach (explode($tag_open, $string) as $key => $value) {
           if(strpos($value, $tag_close) !== FALSE){
                $result[] = substr($value, 0, strpos($value, $tag_close));;
           }
       }
       return $result;
    }
    
    $string = "i love cute animals, like [animal]cat[/animal],
               [animal]dog[/animal] and [animal]panda[/animal]!!!";
    
    echo "
    ";
    print_r(tag_contents($string , "[animal]" , "[/animal]"));
    echo "
    ";
    
    //result
    Array
    (
        [0] => cat
        [1] => dog
        [2] => panda
    )
    
    ответ дан Light93, с репутацией 390, 8.05.2017
  • 1 рейтинг

    В стиле PHP strpos возвращается false, если начальная отметка sm или конечная отметка em не найдены.

    Этот результат (false) отличается от от пустой строки, которую вы получаете, если между начальными и конечными отметками нет ничего.

    function between( $str, $sm, $em )
    {
        $s = strpos( $str, $sm );
        if( $s === false ) return false;
        $s += strlen( $sm );
        $e = strpos( $str, $em, $s );
        if( $e === false ) return false;
        return substr( $str, $s, $e - $s );
    }
    

    Функция вернет только первое совпадение.

    Это очевидно, но стоит упомянуть, что функция сначала будет искать sm, а затем em.

    Это означает, что вы не можете получить желаемый результат / поведение, если сначала нужно выполнить поиск em, а затем строку нужно проанализировать в обратном направлении в поисках sm.

    ответ дан Paolo, с репутацией 9223, 27.01.2017
  • 1 рейтинг

    Немного улучшен код от GarciaWebDev и Henry Wang. Если задано пустое $ start или $ end, функция возвращает значения от начала или до конца строки $. Также доступна опция Inclusive, хотим ли мы включить результат поиска или нет:

    function get_string_between ($string, $start, $end, $inclusive = false){
        $string = " ".$string;
    
        if ($start == "") { $ini = 0; }
        else { $ini = strpos($string, $start); }
    
        if ($end == "") { $len = strlen($string); }
        else { $len = strpos($string, $end, $ini) - $ini;}
    
        if (!$inclusive) { $ini += strlen($start); }
        else { $len += strlen($end); }
    
        return substr($string, $ini, $len);
    }
    
    ответ дан Julius Tilvikas, с репутацией 16, 5.11.2013
  • 1 рейтинг

    Я должен кое-что добавить к посту Юлиуса Тилвикаса. Я искал решение, подобное этому, которое он описал в своем посте. Но я думаю, что есть ошибка. Я не получаю действительно строку между двумя строками, я также получаю больше с этим решением, потому что я должен вычесть длину стартовой строки. Когда это делается, я действительно получаю строку между двумя строками.

    Вот мои изменения его решения:

    function get_string_between ($string, $start, $end, $inclusive = false){
        $string = " ".$string;
    
        if ($start == "") { $ini = 0; }
        else { $ini = strpos($string, $start); }
    
        if ($end == "") { $len = strlen($string); }
        else { $len = strpos($string, $end, $ini) - $ini - strlen($start);}
    
        if (!$inclusive) { $ini += strlen($start); }
        else { $len += strlen($end); }
    
        return substr($string, $ini, $len);
    }
    

    Greetz

    V

    ответ дан Der_V, с репутацией 92, 4.12.2013
  • 1 рейтинг

    Попробуйте это, его работа для меня, получить данные между тест слова.

    $str = "Xdata test HD01 test 1data";  
    $result = explode('test',$str);   
    print_r($result);
    echo $result[1];
    
    ответ дан Dave, с репутацией 2614, 10.11.2016
  • 0 рейтинг

    Это функция, которую я использую для этого. Я объединил два ответа в одной функции для одного или нескольких разделителей.

    function getStringBetweenDelimiters($p_string, $p_from, $p_to, $p_multiple=false){
        //checking for valid main string  
        if (strlen($p_string) > 0) {
            //checking for multiple strings 
            if ($p_multiple) {
                // getting list of results by end delimiter
                $result_list = explode($p_to, $p_string);
                //looping through result list array 
                foreach ( $result_list AS $rlkey => $rlrow) {
                    // getting result start position
                    $result_start_pos   = strpos($rlrow, $p_from);
                    // calculating result length
                    $result_len         =  strlen($rlrow) - $result_start_pos;
    
                    // return only valid rows
                    if ($result_start_pos > 0) {
                        // cleanying result string + removing $p_from text from result
                        $result[] =   substr($rlrow, $result_start_pos + strlen($p_from), $result_len);                 
                    }// end if 
                } // end foreach 
    
            // if single string
            } else {
                // result start point + removing $p_from text from result
                $result_start_pos   = strpos($p_string, $p_from) + strlen($p_from);
                // lenght of result string
                $result_length      = strpos($p_string, $p_to, $result_start_pos);
                // cleaning result string
                $result             = substr($p_string, $result_start_pos+1, $result_length );
            } // end if else 
        // if empty main string
        } else {
            $result = false;
        } // end if else 
    
        return $result;
    
    
    } // end func. get string between
    

    Для простого использования (возвращает два):

    $result = getStringBetweenDelimiters(" one two three ", 'one', 'three');
    

    Для получения каждой строки в массиве результата:

    $result = getStringBetweenDelimiters($table, '
    ', true);
    ответ дан Szekelygobe, с репутацией 36, 6.09.2017
  • 0 рейтинг

    С некоторой ошибкой отлова. В частности, для большинства представленных функций требуется $ end, хотя на самом деле в моем случае это было необязательно. Используйте значение $ end необязательно и оцените значение FALSE, если $ start вообще не существует:

    function get_string_between( $string, $start, $end ){
        $string = " " . $string;
        $start_ini = strpos( $string, $start );
        $end = strpos( $string, $end, $start+1 );
        if ($start && $end) {
            return substr( $string, $start_ini + strlen($start), strlen( $string )-( $start_ini + $end ) );
        } elseif ( $start && !$end ) {
            return substr( $string, $start_ini + strlen($start) );
        } else {
            return FALSE;
        }
    
    }
    
    ответ дан NotaGuruAtAll, с репутацией 155, 1.12.2016
  • 0 рейтинг

    Улучшение Ответ Алехандро . Вы можете оставить аргументы $start или $end пустыми, и они будут использовать начало или конец строки.

    echo get_string_between("Hello my name is bob", "my", ""); //output: " name is bob"
    
    private function get_string_between($string, $start, $end){ // Get
        if($start != ''){ //If $start is empty, use start of the string
            $string = ' ' . $string;
            $ini = strpos($string, $start);
            if ($ini == 0) return '';
            $ini += strlen($start);
        }
        else{
            $ini = 0;
        }
    
        if ($end == '') { //If $end is blank, use end of string
            return substr($string, $ini);
        }
        else{
            $len = strpos($string, $end, $ini) - $ini; //Work out length of string
            return substr($string, $ini, $len);
        }
    }
    
    ответ дан Rikki Masters, с репутацией 3, 25.07.2018
  • 0 рейтинг

    UTF-8 версия ответа @Alejandro Iglesias, будет работать для нелатинских символов:

    function get_string_between($string, $start, $end){
        $string = ' ' . $string;
        $ini = mb_strpos($string, $start, 0, 'UTF-8');
        if ($ini == 0) return '';
        $ini += mb_strlen($start, 'UTF-8');
        $len = mb_strpos($string, $end, $ini, 'UTF-8') - $ini;
        return mb_substr($string, $ini, $len, 'UTF-8');
    }
    
    $fullstring = 'this is my [tag]dog[/tag]';
    $parsed = get_string_between($fullstring, '[tag]', '[/tag]');
    
    echo $parsed; // (result = dog)
    
    ответ дан NXT, с репутацией 1543, 6.07.2017
  • 0 рейтинг

    У меня были некоторые проблемы с функцией get_string_between (), используемой здесь. Итак, я пришел со своей версией. Может быть, это может помочь людям в том же деле, что и у меня.

    protected function string_between($string, $start, $end, $inclusive = false) { 
       $fragments = explode($start, $string, 2);
       if (isset($fragments[1])) {
          $fragments = explode($end, $fragments[1], 2);
          if ($inclusive) {
             return $start.$fragments[0].$end;
          } else {
             return $fragments[0];
          }
       }
       return false;
    }
    
    ответ дан KmeCnin, с репутацией 417, 15.12.2014
  • 0 рейтинг

    Использование:

    function getdatabetween($string, $start, $end){
        $sp = strpos($string, $start)+strlen($start);
        $ep = strpos($string, $end)-strlen($start);
        $data = trim(substr($string, $sp, $ep));
        return trim($data);
    }
    $dt = "Find string between two strings in PHP";
    echo getdatabetween($dt, 'Find', 'in PHP');
    
    ответ дан Pankaj Raturi, с репутацией 37, 3.10.2013
  • 0 рейтинг

    написал это некоторое время назад, нашел его очень полезным для широкого спектра применений.

     $end) {
            $temp = $start;
            $start = $end;
            $end = $temp;
        }
        if ( $returnkeys === true) {
            $length = ($end + strlen($key2)) - $start;
        } else {
            $start = $start + strlen($key1);
            $length = $end - $start;
        }
        return substr($source, $start, $length);
    }
    
    // substr_delbykeys() - Returns a copy of source string with everything between the first occurance of both key substrings removed
    //          - only returns first match, and can be used in loops to iterate through large datasets
    //          - arg 1 is the first key substring to look for
    //          - arg 2 is the second key substring to look for
    //          - arg 3 is the source string the search is performed on.
    //          - arg 4 is boolean and allows you to determine if returned result should include the search keys.
    //          - arg 5 is boolean and can be used to determine whether search should be case-sensative or not.
    //
    
    function substr_delbykeys($key1, $key2, $source, $returnkeys, $casematters) {
        if ($casematters === true) {
            $start = strpos($source, $key1);
            $end = strpos($source, $key2);
        } else {
            $start = stripos($source, $key1);
            $end = stripos($source, $key2);
        }
        if ($start === false || $end === false) { return false; }
        if ($start > $end) {
            $temp = $start; 
            $start = $end;
            $end = $temp;
        }
        if ( $returnkeys === true) {
            $start = $start + strlen($key1);
            $length = $end - $start;
        } else {
            $length = ($end + strlen($key2)) - $start;  
        }
        return substr_replace($source, '', $start, $length);
    }
    ?>
    
    ответ дан Dave, с репутацией 1, 22.12.2014
  • 0 рейтинг

    Получил лучшее решение для этого от tonyspiro

    function getBetween($content,$start,$end){
       $r = explode($start, $content);
       if (isset($r[1])){
           $r = explode($end, $r[1]);
           return $r[0];
       }
       return '';
    }
    
    ответ дан Som, с репутацией 131, 22.03.2018
  • -1 рейтинг
    echo explode('/', explode(')', $string)[0])[1];
    

    Замените «/» своим первым символом / строкой, а «)» своим последним символом / строкой. :)

    ответ дан OMi Shah, с репутацией 29, 7.03.2016
  • -1 рейтинг
    function strbtwn($s,$start,$end){
        $i = strpos($s,$start);
        $j = strpos($s,$end,$i);
        return $i===false||$j===false? false: substr(substr($s,$i,$j-$i),strlen($start));
    }
    

    использование:

    echo strbtwn($s,"

    ","

    ");//

    :)

     --> :)
    
    ответ дан does_not_exist, с репутацией , 17.06.2013
  • -1 рейтинг

    '/ s'

    function getStrBetween($left, $right, $in)
    {
        preg_match('/'.$left.'(.*?)'.$right.'/s', $in, $match);
        return empty($match[1]) ? NULL : $match[1];
    }
    

    попробуйте это;)

    ответ дан GigolNet Guigolachvili, с репутацией 429, 25.02.2015
  • -1 рейтинг

    Я использую это в течение многих лет, и это работает хорошо. Возможно, можно сделать более эффективным, но

    grabstring ("Test string", "", "", 0) возвращает тестовую строку
    grabstring ("Test string", "Test", "", 0) возвращает строку
    grabstring ("Test string", "s", "", 5) возвращает строку

    function grabstring($strSource,$strPre,$strPost,$StartAt) {
    if(@strpos($strSource,$strPre)===FALSE && $strPre!=""){
        return("");
    }
    @$Startpoint=strpos($strSource,$strPre,$StartAt)+strlen($strPre);
    if($strPost == "") {
        $EndPoint = strlen($strSource);
    } else {
        if(strpos($strSource,$strPost,$Startpoint)===FALSE){
            $EndPoint= strlen($strSource);
        } else {
            $EndPoint = strpos($strSource,$strPost,$Startpoint);
        }
    }
    if($strPre == "") {
        $Startpoint = 0;
    }
    if($EndPoint - $Startpoint < 1) {
        return "";
    } else {
            return substr($strSource, $Startpoint, $EndPoint - $Startpoint);
    }
    

    }

    ответ дан carbroker, с репутацией 11, 27.05.2014