197

I need a function that returns the substring between two words (or two characters). I'm wondering whether there is a php function that achieves that. I do not want to think about regex (well, I could do one but really don't think it's the best way to go). Thinking of strpos and substr functions. Here's an example:

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

We call the function: $substring = getInnerSubstring($string,"foo");
It returns: " I wanna a cake ".


Update: Well, till now, I can just get a substring beteen two words in just one string, do you permit to let me go a bit farther and ask if I can extend the use of getInnerSubstring($str,$delim) to get any strings that are between delim value, example:

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

I get an array like {"I like php", "I also like asp", "I feel hero"}.

kaya3
  • 47,440
  • 4
  • 68
  • 97
Nadjib Mami
  • 5,736
  • 9
  • 37
  • 49
  • 7
    If you're already using Laravel, `\Illuminate\Support\Str::between('This is my name', 'This', 'name');` is convenient. https://laravel.com/docs/7.x/helpers#method-str-between – Ryan Apr 22 '20 at 21:40
  • What am I missing ? Why can't you just use string replace and remove 'foo' – Rohit Gupta Jul 04 '22 at 05:16
  • @Ryan Note that something like `\Illuminate\Support\Str::between('first=apples&second=oranges&third=kiwis', 'first=', '&');` will not return "apples", but will instead return "apples&second=oranges". This is because the subsequent '&' is used. For a case like this, the `\Illuminate\Support\Str::betweenFirst` function may work well. – Inertial Ignorance Nov 15 '22 at 01:38

39 Answers39

414

If the strings are different (ie: [foo] & [/foo]), take a look at this post from Justin Cook. I copy his code below:

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)
inexistence
  • 29
  • 2
  • 4
Alejandro García Iglesias
  • 16,222
  • 11
  • 51
  • 64
  • 11
    This func is modified to be inclusive of the start and end. function string_between($string, $start, $end, $inclusive = false){ $string = " ".$string; $ini = strpos($string,$start); if ($ini == 0) return ""; if (!$inclusive) $ini += strlen($start); $len = strpos($string,$end,$ini) - $ini; if ($inclusive) $len += strlen($end); return substr($string,$ini,$len); } – Henry May 30 '13 at 20:08
  • 2
    Is it possible to extend this function so it can give back two strings? Let's say i have a $fullstring of "[tag]dogs[/tag] and [tag]cats[/tag]" and i want an array back which contains "dogs" and "cats". – Leonard Schütz Jul 27 '15 at 22:36
  • 2
    @LeonardSchuetz – Try [this answer](http://stackoverflow.com/a/27078384/2199525) then. – leymannx Sep 29 '15 at 11:34
  • "[tag]dogs[/tag] and [tag]cats[/tag]" still not answered. How to get "dogs" and "cats" in array form? Please advice. – Romnick Susa Feb 03 '16 at 04:07
  • $string = "products/keimav-self-stirring-coffee-mug-gift-set-of-4-multicolor-i109698-s140645.html" , I expect returns "140645" (in between -s and .html) , but it returned "elf-stirring-coffee-mug-gift-set-of-4-multicolor-i109698-s140645" , Can someone help me please. – Dylan B Mar 27 '18 at 18:26
  • @DylanB because it picks the first occurrence it finds of the starting string and takes that until the end string. In this case, the first occurrence of the start string is the `-s` in the word `-self`. I guess you will be better served by a regular expression in your case. – Alejandro García Iglesias Mar 29 '18 at 18:37
  • Does not work with `return mb_substr($string, $ini, $len);`. Should be considered and fixed: Just replace `strpos` with `mb_strpos` and `strlen` with `mb_strlen` and `substr` with `mb_substr`. – Avatar Apr 15 '22 at 16:23
146

Regular expressions is the way to go:

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

onlinePhp

Black
  • 18,150
  • 39
  • 158
  • 271
nkkollaw
  • 1,947
  • 1
  • 19
  • 29
  • 2
    It works great! And for people not used to regEx, just add "\" to escape special characters: http://sandbox.onlinephpfunctions.com/code/76dab69f60af4de53c01efb37213b78d024b23d8 – JCarlosR Jan 19 '20 at 15:39
  • 1
    If you need multiple occurrences try this one [multi](http://sandbox.onlinephpfunctions.com/code/f4e6f606abd48938c0572f3ccab173b8a99a7a12) – user1424074 Jul 27 '20 at 16:22
33
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 '';
    }
}

Sample use:

echo getBetween("abc","a","c"); // returns: 'b'

echo getBetween("hello","h","o"); // returns: 'ell'

echo getBetween("World","a","r"); // returns: ''
Dinesh Patil
  • 615
  • 2
  • 15
  • 37
daniel
  • 339
  • 3
  • 2
19

use strstr php function twice.

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

outputs: "is a great day to"

Bryce
  • 988
  • 9
  • 16
19
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] : '';
}

Example of use:

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

If you want to remove surrounding whitespace, use trim. Example:

var_dump(trim(getInnerSubstring('foo Hello world foo','foo')));
// prints: string(11) "Hello world"
Christian
  • 27,509
  • 17
  • 111
  • 155
  • 1
    This is neat because it's a one-liner but unfortunately it is limited to having a unique delimiter, i.e. if you need the substring between "foo" and "bar" you will have to use some other strategy. – mastazi May 08 '17 at 01:23
15
function getInbetweenStrings($start, $end, $str){
    $matches = array();
    $regex = "/$start([a-zA-Z0-9_]*)$end/";
    preg_match_all($regex, $str, $matches);
    return $matches[1];
}

for examle you want the array of strings(keys) between @@ in following example, where '/' doesn't fall in-between

$str = "C://@@ad_custom_attr1@@/@@upn@@/@@samaccountname@@";
$str_arr = getInbetweenStrings('@@', '@@', $str);

print_r($str_arr);
Ravi Verma
  • 225
  • 2
  • 4
14

I like the regular expression solutions but none of the others suit me.

If you know there is only gonna be 1 result you can use the following:

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

Change BEFORE and AFTER to the desired delimiters.

Also keep in mind this function will return the whole string in case nothing matched.

This solution is multiline but you can play with the modifiers depending on your needs.

ragnar
  • 1,252
  • 11
  • 18
  • Please explain your reason for using the `m` pattern modifier. – mickmackusa Jul 29 '21 at 20:52
  • https://www.php.net/manual/en/reference.pcre.pattern.modifiers.php – ragnar Aug 12 '21 at 10:20
  • Great. Now please explain why you are using it to modify pattern. Also, why make three capture groups when you only use one? – mickmackusa Aug 12 '21 at 11:50
  • The modifiers are explained in the link I posted, so no much more I can add but it is basically for multiline match. Three groups are captured because before and after the delimiters anything can go but we only want to capture what is inbetween them. – ragnar Aug 24 '21 at 13:19
  • 2
    Then I will explain what you missed. `m` is a pattern modifier that only affects a pattern containing `^` or `$`. The `s` modifier makes sense because it is affecting `.` characters in the pattern. The `m` serves no purpose. – mickmackusa Aug 24 '21 at 21:02
12

Not a php pro. but i recently ran into this wall too and this is what i came up with.

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 "<pre>";
print_r(tag_contents($string , "[animal]" , "[/animal]"));
echo "</pre>";

//result
Array
(
    [0] => cat
    [1] => dog
    [2] => panda
)
Light93
  • 952
  • 1
  • 8
  • 18
  • Best answer for this question, as it finds all the substrings between two string not just the first one. – Sos. Oct 20 '21 at 23:39
7

A vast majority of answers here don't answer the edited part, I guess they were added before. It can be done with regex, as one answer mentions. I had a different approach.


This function searches $string and finds the first string between $start and $end strings, starting at $offset position. It then updates the $offset position to point to the start of the result. If $includeDelimiters is true, it includes the delimiters in the result.

If the $start or $end string are not found, it returns null. It also returns null if $string, $start, or $end are an empty string.

function str_between(string $string, string $start, string $end, bool $includeDelimiters = false, int &$offset = 0): ?string
{
    if ($string === '' || $start === '' || $end === '') return null;

    $startLength = strlen($start);
    $endLength = strlen($end);

    $startPos = strpos($string, $start, $offset);
    if ($startPos === false) return null;

    $endPos = strpos($string, $end, $startPos + $startLength);
    if ($endPos === false) return null;

    $length = $endPos - $startPos + ($includeDelimiters ? $endLength : -$startLength);
    if (!$length) return '';

    $offset = $startPos + ($includeDelimiters ? 0 : $startLength);

    $result = substr($string, $offset, $length);

    return ($result !== false ? $result : null);
}

The following function finds all strings that are between two strings (no overlaps). It requires the previous function, and the arguments are the same. After execution, $offset points to the start of the last found result string.

function str_between_all(string $string, string $start, string $end, bool $includeDelimiters = false, int &$offset = 0): ?array
{
    $strings = [];
    $length = strlen($string);

    while ($offset < $length)
    {
        $found = str_between($string, $start, $end, $includeDelimiters, $offset);
        if ($found === null) break;

        $strings[] = $found;
        $offset += strlen($includeDelimiters ? $found : $start . $found . $end); // move offset to the end of the newfound string
    }

    return $strings;
}

Examples:

str_between_all('foo 1 bar 2 foo 3 bar', 'foo', 'bar') gives [' 1 ', ' 3 '].

str_between_all('foo 1 bar 2', 'foo', 'bar') gives [' 1 '].

str_between_all('foo 1 foo 2 foo 3 foo', 'foo', 'foo') gives [' 1 ', ' 3 '].

str_between_all('foo 1 bar', 'foo', 'foo') gives [].

Quirinus
  • 442
  • 1
  • 5
  • 9
6
<?php
  function getBetween($content,$start,$end){
    $r = explode($start, $content);
    if (isset($r[1])){
        $r = explode($end, $r[1]);
        return $r[0];
    }
    return '';
  }
?>

Example:

<?php 
  $content = "Try to find the guy in the middle with this function!";
  $start = "Try to find ";
  $end = " with this function!";
  $output = getBetween($content,$start,$end);
  echo $output;
?>

This will return "the guy in the middle".

Dave
  • 3,073
  • 7
  • 20
  • 33
Asif Rahman
  • 73
  • 1
  • 8
6

If you're using foo as a delimiter, then look at explode()

Karl Andrew
  • 1,563
  • 11
  • 14
5

Simple, short, and sweet. It's up to you to make any enhancements.

function getStringBetween($str, $start, $end) 
{
    $pos1 = strpos($str, $start);
    $pos2 = strpos($str, $end);
    return substr($str, $pos1+1, $pos2-($pos1+1));
 }
nxy
  • 93
  • 2
  • 4
3

If you have multiple recurrences from a single string and you have different [start] and [\end] pattern. Here's a function which output an array.

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

Improvement of Alejandro's answer. You can leave the $start or $end arguments empty and it will use the start or end of the string.

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);
    }
}
Tim Diekmann
  • 7,755
  • 11
  • 41
  • 69
3

Here's a function

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

Use it like

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

echo $substring;

Output (note that it returns spaces in front and at the and of your string if exist)

I wanna a cake

If you want to trim result use function like

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

Result: This function will return false if $boundstring was not found in $string or if $boundstring exists only once in $string, otherwise it returns substring between first and last occurrence of $boundstring in $string.


References
Wh1T3h4Ck5
  • 8,399
  • 9
  • 59
  • 79
  • you're using an if-clause without brackets, but you probably know it's a bad idea? – xmoex Jan 17 '17 at 10:28
  • @xmoex, What `IF` clause you're talking about? maybe I made some typo but to be honest, I can't see anything weird right now. Both `IF`s I have used in function above has proper brackets surrounding condition. First `IF` also have curly brackets (braces) that surround 2 lines block, 2nd `IF` doesn't need 'em because it's single line code. What I'm missing? – Wh1T3h4Ck5 Jan 17 '17 at 13:59
  • I'm talking about the single line. I thought the editor of your post erased it but then I saw it wasn't there in the first place. imvho this is a common source of sometimes hard to find bugs if you change the code in the future. – xmoex Jan 17 '17 at 23:38
  • @xmoex **Highly disagree.** After almost 20 years in the business I can say that braces are extremely rare cause of bugs (proper indention is required anyway). Surrounding single line with braces is ugly (matter of opinion) and make code bigger (matter of fact). In most companies removing unnecessary braces is required on code completion. True, it might be hard to spot during debugging for inexperienced users but that's not global problem, just a step on their learning path. Me personally, never had big problems with braces, even in case of complex nesting. – Wh1T3h4Ck5 Jan 18 '17 at 07:11
  • @Wh1T3h4Ck5 I respect your opinion and your experiences, but I'm not convinced at all. Braces don't make the code bigger from a system point of view. It enlarges the file size, but what does the compiler care? And if using js you'll probably automatically uglyfy code before going live. I think using braces always hurts less then omitting them "sometimes"... – xmoex Jan 19 '17 at 13:16
  • @xmoex Course m8, it's only matter of opinion. Anyway, braces can't hurt code at all. Personally, I put empty lines before/after single line "blocks" when coding so it's clearly visible. – Wh1T3h4Ck5 Jan 20 '17 at 12:19
  • This function will not do. If you have "foo first foo second foo third foo" it will return " first foo second foo third ". strrpos is the culprit here. – Quirinus May 06 '19 at 18:58
  • Yes, this is an old post, but let's make a point of steering future researchers toward a professional standard (PSR-12 is a pretty solid guide). https://www.php-fig.org/psr/psr-12/#:~:text=The%20body%20of%20each%20structure,added%20to%20the%20body. – mickmackusa Aug 13 '21 at 00:43
2
private function getStringBetween(string $from, string $to, string $haystack): string
{
    $fromPosition = strpos($haystack, $from) + strlen($from);
    $toPosition = strpos($haystack, $to, $fromPosition);
    $betweenLength = $toPosition - $fromPosition;
    return substr($haystack, $fromPosition, $betweenLength);
}
fabpico
  • 2,628
  • 4
  • 26
  • 43
1

Use:

<?php

$str = "...server daemon started with pid=6849 (parent=6848).";
$from = "pid=";
$to = "(";

echo getStringBetween($str,$from,$to);

function getStringBetween($str,$from,$to)
{
    $sub = substr($str, strpos($str,$from)+strlen($from),strlen($str));
    return substr($sub,0,strpos($sub,$to));
}

?>
MD SHAHIDUL ISLAM
  • 14,325
  • 6
  • 82
  • 89
1

A bit improved code from GarciaWebDev and Henry Wang. If empty $start or $end is given, function returns values from the beginning or to the end of the $string. Also Inclusive option is available, whether we want to include search result or not:

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

I have to add something to the post of Julius Tilvikas. I looked for a solution like this one he described in his post. But i think there is a mistake. I don't get realy the string between two string, i also get more with this solution, because i have to substract the lenght of the start-string. When do this, i realy get the String between two strings.

Here are my changes of his solution:

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
  • 177
  • 1
  • 16
1

Try this, Its work for me, get data between test word.

$str = "Xdata test HD01 test 1data";  
$result = explode('test',$str);   
print_r($result);
echo $result[1];
Dave
  • 3,073
  • 7
  • 20
  • 33
  • Because you are unconditionally accessing the first element of the array, your explode should limit the number of elements generated to 3 to prevent unnecessary extra explosions (not that your example allows more than 3). – mickmackusa Aug 13 '21 at 00:47
1

In PHP's strpos style this will return false if the start mark sm or the end mark em are not found.

This result (false) is different from an empty string that is what you get if there is nothing between the start and end marks.

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

The function will return only the first match.

It's obvious but worth mentioning that the function will first look for sm and then for em.

This implies you may not get the desired result/behaviour if em has to be searched first and then the string have to be parsed backward in search of sm.

Paolo
  • 15,233
  • 27
  • 70
  • 91
1

This is the function I'm using for this. I combined two answers in one function for single or multiple delimiters.

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

For simple use (returns two):

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

For getting each row in a table to result array :

$result = getStringBetweenDelimiters($table, '<tr>', '</tr>', true);
Szekelygobe
  • 2,309
  • 1
  • 19
  • 25
1

an edited version of what Alejandro García Iglesias put.

This allows you to pick a specific location of the string you want to get based on the number of times the result is found.

function get_string_between_pos($string, $start, $end, $pos){
    $cPos = 0;
    $ini = 0;
    $result = '';
    for($i = 0; $i < $pos; $i++){
      $ini = strpos($string, $start, $cPos);
      if ($ini == 0) return '';
      $ini += strlen($start);
      $len = strpos($string, $end, $ini) - $ini;
      $result = substr($string, $ini, $len);
      $cPos = $ini + $len;
    }
    return $result;
  }

usage:

$text = 'string has start test 1 end and start test 2 end and start test 3 end to print';

//get $result = "test 1"
$result = $this->get_string_between_pos($text, 'start', 'end', 1);

//get $result = "test 2"
$result = $this->get_string_between_pos($text, 'start', 'end', 2);

//get $result = "test 3"
$result = $this->get_string_between_pos($text, 'start', 'end', 3);

strpos has an additional optional input to start its search at a specific point. so I store the previous position in $cPos so when the for loop checks again, it starts at the end of where it left off.

SwiftNinjaPro
  • 787
  • 8
  • 17
1

easy solution using substr

$posStart = stripos($string, $start) + strlen($start);
$length = stripos($string, $end) - $posStart;

$substring = substr($string,  $posStart,  $length);
0

Use:

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

I had some problems with the get_string_between() function, used here. So I came with my own version. Maybe it could help people in the same case as mine.

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
  • 507
  • 3
  • 16
0

wrote these some time back, found it very useful for a wide range of applications.

<?php

// substr_getbykeys() - Returns everything in a source string that exists between the first occurance of each of the two key substrings
//          - only returns first match, and can be used in loops to iterate through large datasets
//          - arg 1 is the first substring to look for
//          - arg 2 is the second 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_getbykeys($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) {
        $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
0

With some error catching. Specifically, most of the functions presented require $end to exist, when in fact in my case I needed it to be optional. Use this is $end is optional, and evaluate for FALSE if $start doesn't exist at all:

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
  • 503
  • 7
  • 19
0

UTF-8 version of @Alejandro Iglesias answer, will work for non-latin characters:

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
  • 1,981
  • 1
  • 24
  • 30
0

I use

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

Subtitue <TAG> for whatever delimiter you want.

0

It can be easily done using this small function:

function getString($string, $from, $to) {
    $str = explode($from, $string);
    $str = explode($to, $str[1]);
    return $s[0];
}
$myString = "<html>Some code</html>";
print getString($myString, '<html>', '</html>');

// Prints: Some code
0

Consider this function. It accepts both position number, and strings arguments:

function get_string_between($string, $start = '', $end = ''){
    if (empty($start)) {
      $start = 0;
    }elseif (!is_numeric($start)) {
      $start = strpos($string, $start) + strlen($start);
    }

    if (empty($end)) {
      $end = strlen($string);
    }elseif (!is_numeric($end)) {
      $end = strpos($string, $end);
    }

    return substr($string, $start, ($end - $start));
  }

Results:

echo get_string_between($string); // result = this is my [tag]dog[/tag]
echo get_string_between($string, 0); // result = this is my [tag]dog[/tag]
echo get_string_between($string, ''); // result = this is my [tag]dog[/tag]
echo get_string_between($string, '[tag]'); // result = dog[/tag]
echo get_string_between($string, 0, '[/tag]'); // result = this is my [tag]dog
echo get_string_between($string, '', '[/tag]'); // result = this is my [tag]dog
echo get_string_between($string, '[tag]', '[/tag]'); // result = dog
echo get_string_between($string, '[tag]', strlen($string)); // dog[/tag]
hamlet237
  • 41
  • 4
0
function img($n,$str){

    $first=$n."tag/";
    $n+=1;
    $last=$n."tag/";
    $frm = stripos($str,$first);
    $to = stripos($str,$last);
    echo $frm."<br>";
    echo $to."<br>";
    $to=($to=="")?(strlen($str)-$frm):($to-$frm);
    $final = substr($str,$frm,$to);
    echo $to."<br>";
    echo $final."<br>";

}


$str = "1tag/Ilove.php2tag/youlike.java3tag/youlike.php";
img(1,$str);

img(2,$str);

img(3,$str);
0

Well , for me just 3 lines with explode, but you must initiate left_border and right_border of the substring.

function getInnerSubstring($substring,$left,$right){
    $string = explode($left,$substring)[1];
    return explode($right,$string)[0];
}
0

Here is a code sample for getting text between two strings with offset as a string.

get_string_between($string, $start, $end, $offset = null)
{
    $offset = !empty($offset) ? (strpos($string, $offset) + strlen($offset)) : 0;


    if (empty($start) || empty($end)) {
        return null;
    }

    //Index of start string
    $start = strpos($string, $start, $offset) + strlen($start);
    //Index of end string
    $end = strpos($string, $end, $start);
    $length = $end - $start;
    return substr($string, $start, $length);
}
George John
  • 2,629
  • 2
  • 21
  • 16
-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));
}

usage:

echo strbtwn($s,"<h2>","</h2>");//<h2>:)</h2> --> :)
-1

I have been using this for years and it works well. Could probably be made more efficient, but

grabstring("Test string","","",0) returns Test string
grabstring("Test string","Test ","",0) returns string
grabstring("Test string","s","",5) returns string

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
  • 21
  • 2
-1
echo explode('/', explode(')', $string)[0])[1];

Replace '/', with your first character/string and ')' with your ending character/string. :)

OMi Shah
  • 5,768
  • 3
  • 25
  • 34
-1

Get specific text's and push into an array in php:

<!DOCTYPE html>
<html>
<body>

<?php
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 = '.layout { 

color: {{ base_color }} 

}

li { 

color: {{ sub_color }} 

} 

.text { 

color: {{ txt_color }}

 }

 .btn { 

color: {{ btn_color }}

 }

.more_text{

color:{{more_color}}

}';


$arr = [];

while(1){
  $parsed = get_string_between($fullstring, '{{', '}}');
  if(!$parsed)
    break;
  array_push($arr,$parsed);
  $strposition = strpos($fullstring,"}}");
  $nextString = substr($fullstring, $strposition+1, strlen($fullstring));
  $fullstring = $nextString;
  echo "<br>";
}
print_r($arr);

?>

</body>
</html>

Without array:

<?php
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 = '.layout { 

color: {{ base_color }} 

}

li { 

color: {{ sub_color }} 

} 

.text { 

color: {{ txt_color }}

 }

 .btn { 

color: {{ btn_color }}

 }

.more_text{

color:{{more_color}}

}';


while(1){
  $parsed = get_string_between($fullstring, '{{', '}}');
  if(!$parsed)
    break;
  echo $parsed;
  $strposition = strpos($fullstring,"}}");
  $nextString = substr($fullstring, $strposition+1, strlen($fullstring));
  $fullstring = $nextString;
  echo "<br>";
}

?>

For single output, remove the array and loops.

<?php
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 = '.layout { 

color: {{ base_color }} 

}

li { 

color: {{ sub_color }} 

} 

.text { 

color: {{ txt_color }}

 }

 .btn { 

color: {{ btn_color }}

 }

.more_text{

color:{{more_color}}

}';

  $parsed = get_string_between($fullstring, '{{', '}}');
  echo $parsed;

?>
Maizied Hasan Majumder
  • 1,197
  • 1
  • 12
  • 25