2009-09-18 12 views
18

¿Cuál es la mejor manera de obtener el contenido entre dos cadenas por ejemplo,contenido entre dos cadenas de PHP

ob_start(); 
include('externalfile.html'); ## see below 
$out = ob_get_contents(); 
ob_end_clean(); 

preg_match('/{FINDME}(.|\n*)+{\/FINDME}/',$out,$matches); 
$match = $matches[0]; 

echo $match; 

## I have used .|\n* as it needs to check for new lines. Is this correct? 

## externalfile.html 

{FINDME} 
Text Here 
{/FINDME} 

Por alguna razón, esto parece funcionar en un lugar de mi código y no en otro. ¿Voy por esto de la manera correcta? ¿O hay un mejor camino?

también entrega la señal del tampón El modo de hacer esto o file_get_contents?

¡Gracias de antemano!

+0

Si funciona en algunas situaciones y otras no, debería proporcionar ejemplos de cuándo funciona y cuándo no. – Welbog

Respuesta

35
  • Use # en lugar de / para que no tenga que escapar de ellos.
  • modifiers marcas . y \s también incluyen nuevas líneas.
  • { y } tiene varias funcionalidades como desde n a m veces en {n,m}.
  • La básica

    preg_match('#\\{FINDME\\}(.+)\\{/FINDME\\}#s',$out,$matches); 
    
  • El avanzado para varias etiquetas, etc (estilo no es tan agradable por el javascript).

    $delimiter = '#'; 
    $startTag = '{FINDME}'; 
    $endTag = '{/FINDME}'; 
    $regex = $delimiter . preg_quote($startTag, $delimiter) 
            . '(.*?)' 
            . preg_quote($endTag, $delimiter) 
            . $delimiter 
            . 's'; 
    preg_match($regex,$out,$matches); 
    

poner este código en una función

  • Para cualquier archivo que no desea execue ningún código php callejero, debe usar file_get_contents. include/require ni siquiera debería ser una opción allí.
+2

Apuesto {FINDME} es solo para la ilustración –

39

Es posible también utilizar substr y strpos para esto.

$startsAt = strpos($out, "{FINDME}") + strlen("{FINDME}"); 
$endsAt = strpos($out, "{/FINDME}", $startsAt); 
$result = substr($out, $startsAt, $endsAt - $startsAt); 

Usted tendrá que añadir la comprobación de errores para manejar el caso en que no lo hace findme.

+1

Esta es la mejor manera de hacerlo cuando es posible –

+0

de acuerdo con Cem Kalyoncu – Peter

+0

Gracias por la solución alternativa, resolvió mi problema. Estaba realizando una preg_match con una cadena grande que devolvió una matriz vacía. Tu solución solucionó mi problema. – meenxo

1

Los saltos de línea pueden causar problemas en RegEx, intente eliminarlos o reemplazarlos con \ n antes del procesamiento.

-1

Forma rápida de poner todo en una sola cadena.

$newlines = array("\t","\n","\r","\x20\x20","\0","\x0B"); 
$one_string = str_replace($newlines, "", html_entity_decode($content)); 
0
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://@@[email protected]@/@@[email protected]@/@@[email protected]@"; 
$str_arr = getInbetweenStrings('@@', '@@', $str); 

print_r($str_arr); 
+0

Esto simplemente no funciona. p.ej. 'getInbetweenStrings ('start', 'end', 'start get this string end');' – billynoah

4

Me encanta estas dos soluciones

function GetBetween($content,$start,$end) 
{ 
    $r = explode($start, $content); 
    if (isset($r[1])){ 
     $r = explode($end, $r[1]); 
     return $r[0]; 
    } 
    return ''; 
} 


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

También hicieron pocos puntos de referencia, así como con las dos soluciones anteriores y ambos están dando casi al mismo tiempo. Puedes probarlo también. Le di a ambas funciones un archivo para leer que tenía aproximadamente 60000 caracteres (revisado con el recuento de palabras de la Sra. Word) y ambas funciones dieron como resultado aproximadamente 0,000999 segundos para encontrarlas.

$startTime = microtime(true); 
GetBetween($str, '<start>', '<end>'); 
echo "Explodin Function took: ".(microtime(true) - $startTime) . " to finish<br />"; 

$startTime = microtime(true); 
get_string_between($str, '<start>', '<end>'); 
echo "Subsring Function took: ".(microtime(true) - $startTime) . " to finish<br />"; 
+0

Esto es genial. ¿Se puede hacer que funcione para encontrar varias coincidencias? Entonces devuelve una matriz con todas las coincidencias? –

0

Esta es una solución PHP que devuelve las cadenas encontradas entre las etiquetas en un pajar. Funciona, pero no he probado la eficiencia. Lo necesitaba y me inspiré en la respuesta de Adam Wright en esta página.

Devuelve una matriz() que contiene todas las cadenas encontradas entre $ etiqueta y $ end_symbold. $ Etiqueta en $ haystack, o FALSE si no se encontró ninguna etiqueta $ end_symbol. $, Por lo tanto, no existe par de etiquetas en $ haystack.

function str_between_tags($haystack, $tag, $end_symbol){ 
    $c_end_tags = substr_count($haystack, $end_symbol.$tag); 
    if(!$c_end_tags) return FALSE; 

    for($i=0; $i<$c_end_tags; $i++){ 
     $p_s = strpos($haystack, $tag, (($p_e)?$p_e+strlen($end_symbol.$tag):NULL)) + strlen($tag); 
     $p_e = strpos($haystack, $end_symbol.$tag, $p_s); 
     $result[] = substr($haystack, $p_s, $p_e - $p_s); 
    } 
    return $result; 
} 
Cuestiones relacionadas