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

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

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

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

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

Обновление: Хорошо, до сих пор я могу просто получить подстроку, состоящую из двух слов только в одной строке, разрешить ли я отпустить меня немного дальше и спросить, могу ли я расширить использование getInnerSubstring($str,$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"} .

Если строки разные (например: [foo] & [/ 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) 

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

 $str = 'before-str-after'; preg_match('/before-(.*?)-after/', $str, $match); echo $match[1]; 
 function GetBetween($var1="",$var2="",$pool){ $temp1 = strpos($pool,$var1)+strlen($var1); $result = substr($pool,$temp1,strlen($pool)); $dd=strpos($result,$var2); if($dd == 0){ $dd = strlen($result); } return substr($result,0,$dd); } 

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

 echo GetBetween("a","c","abc"); // returns: b echo GetBetween("h","o","hello"); // returns: ell 
 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" 
 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); 

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

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

Пример:

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

Это вернет «парня посередине».

Если у вас несколько повторений из одной строки, и у вас разные шаблоны [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; } 

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

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

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

Измените BEFORE и AFTER на нужные разделители.

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

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

используйте функцию 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"

Вот функция

 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 в $string .


Рекомендации

  • StrPos ()
  • strrpos ()
  • зиЬзЬг ()
  • отделка()

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

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

Немного улучшенный код от 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); } 

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

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

 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

В

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

 $str = "Xdata test HD01 test 1data"; $result = explode('test',$str); print_r($result); echo $result[1]; 

В стиле strpos PHP это вернет 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 .

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

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

У меня были некоторые проблемы с функцией 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; } 

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

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

С некоторой ошибкой ловить. В частности, большинство представленных функций требуют, чтобы end 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; } } 

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

 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 ) 

Версия 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) 

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

 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, '<tr>', '</tr>', true); 

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

grabstring ("тестовая строка", "", "", 0) возвращает тестовую строку
grabstring («тестовая строка», «тест», «», 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); } 

}

 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,"<h2>","</h2>");//<h2>:)</h2> --> :) 

'/ S'

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

попробуй это 😉

 echo explode('/', explode(')', $string)[0])[1]; 

Замените '/' вашим первым символом / строкой и ')' вашим конечным символом / строкой. 🙂