Как получить подстроку между двумя строками в PHP?
мне нужна функция, которая возвращает подстроку между двумя словами (или два символа).
Мне интересно, есть ли функция php, которая достигает этого. Я не хочу думать о регулярном выражении (ну, я мог бы сделать это, но действительно не думаю, что это лучший способ пойти). Думал о strpos и substr функции.
Вот пример:
$string = "foo I wanna a cake foo";
мы вызываем функцию: $substring = getInnerSubstring($string,"foo");
Он возвращает: "я хочу торт".
спасибо заранее.
обновление:
Ну, до сих пор я могу просто получить подстроку beteen два слова в одной строке, вы позволите мне пойти немного дальше и спросить, могу ли я расширить использование 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"}.
30 ответов:
Если строки разные (т. е.: [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'; if (preg_match('/before-(.*?)-after/', $str, $match) == 1) { echo $match[1]; }
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: ''
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);
Мне нравятся решения регулярных выражений, но ни один из других мне не подходит.
Если вы знаете, что будет только 1 результат, вы можете использовать следующее:
$between = preg_replace('/(.*)BEFORE(.*)AFTER(.*)/sm', '', $string);изменить до и после нужных разделителей.
также имейте в виду, что эта функция вернет всю строку в случае, если ничего не соответствует.
данное решение является многострочным, но вы можете играть с модификаторами в зависимости от ваших потребностей.
<?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; ?>это вернет "парень в середине".
используйте функцию PHP strstr дважды.
$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"
Если у вас есть несколько рецидивов из одной строки, и у вас есть другой шаблон [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; }
здесь функция
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);результат: эта функция возвращает ложные если
$boundstringне был найден в$stringили$boundstringсуществует только один раз в$string, в противном случае это возвращает подстроку между первым и последним вхождением$boundstringна$string.
ссылки
использование:
<?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 и Генри Ванга. Если задано пустое значение $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
V
попробуйте это, его работа для меня, получить данные между тегами тест слово.
$str = "Xdata test HD01 test 1data"; $result = explode('test',$str); print_r($result); echo $result[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.
Не 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 )
Я использую
if (count(explode("<TAG>", $input))>1){ $content = explode("</TAG>",explode("<TAG>", $input)[1])[0]; }else{ $content = ""; }Subtitue
для любого разделителя, который вы хотите.
использование:
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 является необязательным, и оценить для 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; } }
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);
есть лучшее решение для этого из tonyspiro
function getBetween($content,$start,$end){ $r = explode($start, $content); if (isset($r[1])){ $r = explode($end, $r[1]); return $r[0]; } return ''; }
улучшение Алехандро!--5-->. Вы можете оставить
$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); } }
Я использую это в течение многих лет, и она работает хорошо. Возможно, можно было бы сделать более эффективным, но
grabstring ("тестовая строка","","",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); }}
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];заменить '/', с вашим первым символом/строкой и') ' с вашим конечным символом / строкой. :)
Comments