¿Cómo obtener una subcadena entre dos cadenas en PHP?

Necesito una función que devuelva la subcadena entre dos palabras (o dos caracteres). Me pregunto si hay una función de php que logre eso. No quiero pensar en regex (bueno, podría hacer uno pero realmente no creo que sea la mejor manera de hacerlo). Pensando en strpos y funciones substr . Aquí hay un ejemplo:

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

Llamamos a la función: $substring = getInnerSubstring($string,"foo");
Vuelve: “Quiero un pastel”.

Gracias por adelantado.

Actualización: Bueno, hasta ahora, solo puedo obtener una subcadena de dos palabras en una sola cadena, ¿me permiten dejarme ir un poco más lejos y preguntar si puedo extender el uso de getInnerSubstring($str,$delim) para obtener cualquier cadena que esté entre el valor delim, ejemplo:

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

Obtengo una matriz como {"I like php", "I also like asp", "I feel hero"} .

Si las cadenas son diferentes (es decir: [foo] y [/ foo]), eche un vistazo a esta publicación de Justin Cook. Copio su código a continuación:

 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) 

Las expresiones regulares es el camino a seguir:

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

Uso de muestra:

 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] : ''; } 

Ejemplo de uso:

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

Si desea eliminar el espacio en blanco circundante, use trim . Ejemplo:

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

por ejemplo, desea la matriz de cadenas (claves) entre @@ en el siguiente ejemplo, donde ‘/’ no se interpone

 $str = "C://@@[email protected]@/@@[email protected]@/@@[email protected]@"; $str_arr = getInbetweenStrings('@@', '@@', $str); print_r($str_arr); 

Si usa foo como delimitador, mire explode()

  

Ejemplo:

  

Esto devolverá “el chico en el medio”.

use la función strstr php dos veces.

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

salidas: "is a great day to"

Si tiene múltiples recurrencias de una sola cadena y tiene un patrón diferente [inicio] y [\ end]. Aquí hay una función que da salida a una matriz.

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

Me gustan las soluciones de expresión regular, pero ninguna de las otras me sirve.

Si sabes que solo va a haber 1 resultado, puedes usar lo siguiente:

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

Cambie ANTES y DESPUÉS a los delimitadores deseados.

También tenga en cuenta que esta función devolverá toda la cadena en caso de que no coincida nada.

Esta solución es multilínea, pero puedes jugar con los modificadores según tus necesidades.

Aquí hay una función

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

Úselo como

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

Salida (tenga en cuenta que devuelve espacios delante y al final de su cadena si existen)

Quiero un pastel

Si desea recortar el resultado, use la función como

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

Resultado : Esta función devolverá false si $boundstring no se encontró en $string o si $boundstring existe solo una vez en $string , de lo contrario, devuelve una subcadena entre la primera y la última ocurrencia de $boundstring en $string .


Referencias

  • Strpos ()
  • strrpos ()
  • substr ()
  • recortar()

Utilizar:

  

Un código poco mejorado de GarciaWebDev y Henry Wang. Si se da $ $ vacío o $ end, la función devuelve valores desde el comienzo o hasta el final de $ string. También la opción Inclusiva está disponible, si queremos incluir el resultado de la búsqueda o no:

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

Tengo que agregar algo a la publicación de Julius Tilvikas. Busqué una solución como esta que describió en su publicación. Pero creo que hay un error. No entiendo realmente la cuerda entre dos cuerdas, también obtengo más con esta solución, porque tengo que restar la longitud de la cuerda de inicio. Cuando hago esto, realmente consigo la cadena entre dos cadenas.

Aquí están mis cambios de su solución:

 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

Prueba esto, su trabajo para mí, obtener datos entre la palabra de prueba .

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

En el estilo strpos de PHP esto devolverá false si la marca de inicio sm o la marca final em no se encuentran.

Este resultado ( false ) es diferente de una cadena vacía que es lo que obtienes si no hay nada entre las marcas de inicio y final.

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

La función devolverá solo la primera coincidencia.

Es obvio, pero vale la pena mencionar que la función primero buscará sm y luego em .

Esto implica que puede no obtener el resultado / comportamiento deseado si se debe buscar primero y luego se debe analizar la cadena hacia atrás en la búsqueda de sm .

Utilizar:

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

Tuve algunos problemas con la función get_string_between (), que se usa aquí. Así que vine con mi propia versión. Tal vez podría ayudar a la gente en el mismo caso que el mío.

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

escribió esto hace algún tiempo, lo encontró muy útil para una amplia gama de aplicaciones.

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

Con algún error atrapando. Específicamente, la mayoría de las funciones presentadas requieren $ end para existir, cuando en realidad en mi caso lo necesitaba para ser opcional. Usar esto es $ end es opcional, y evaluar para FALSE si $ start no existe en absoluto:

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

No es un profesional de php. pero recientemente me topé con esta pared también y esto es lo que se me ocurrió.

 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 )

La versión UTF-8 de la respuesta de @Alejandro Iglesias funcionará para caracteres no latinos:

 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) 

Esta es la función que estoy usando para esto. Combiné dos respuestas en una función para delimitadores únicos o múltiples.

 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 

Para un uso simple (devuelve dos):

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

Para obtener cada fila en una tabla para obtener una matriz:

 $result = getStringBetweenDelimiters($table, '', '', true); 

He estado usando esto por años y funciona bien. Probablemente podría hacerse más eficiente, pero

grabstring (“Cadena de prueba”, “”, “”, 0) devuelve Cadena de prueba
grabstring (“Cadena de prueba”, “Prueba”, “”, 0) devuelve cadena
grabstring (“Cadena de prueba”, “s”, “”, 5) devuelve cadena

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

uso:

 echo strbtwn($s,"

","

");//

:)

--> :)

‘/ s’

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

prueba esto 😉

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

Reemplace ‘/’, con su primer carácter / cadena y ‘)’ con su carácter / cuerda final. 🙂