Как получить подстроку между двумя строками в PHP?
мне нужна функция, которая возвращает подстроку между двумя словами (или два символа).
Мне интересно, есть ли функция php, которая достигает этого. Я не хочу думать о regex (ну, я мог бы сделать один, но действительно не думаю, что это лучший способ). Думал о 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"}
.
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);
измените BEFORE и AFTER на нужные разделители.
также имейте в виду, что эта функция вернет всю строку, если ничего не совпадет.
данное решение является многострочным, но вы можете играть с модификаторами в зависимости от ваших потребностей.
<?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;
?>
это вернет "парня в середине".
используйте функцию 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"
Если у вас есть несколько рецидивов из одной строки, и у вас есть другой шаблон [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;
Output (обратите внимание, что он возвращает пробелы спереди и на и вашей строки, если они существуют)
Я хочу торт
если вы хотите обрезать результат функции как
$substring = getInnerSubstring($string, "foo", true);
результат: эта функция возвращает false если $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 и 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
V
попробуйте это, его работа для меня, получить данные между тегами тест слово.
$str = "Xdata test HD01 test 1data";
$result = explode('test',$str);
print_r($result);
echo $result[1];
в PHP strpos
стиль это вернет false
если начальная отметка sm
или конечный знак em
не нашли.
этот результат (false
) is разные из пустой строки это то, что вы получаете, если между начальными и конечными метками ничего нет.
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) возвращает string
grabstring ("тестовая строка","s","", 5) возвращает 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);
}
}
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];
замените ' / ' на ваш первый символ/строку и ')' на ваш конечный символ / строку. :)