2009-10-07 35 views
11

espero que este sea rápido y simple, usando PHP Estoy tratando de dividir una cadena en una matriz, pero solo por la última instancia de espacio en blanco. Hasta ahora tengo ...Regex para dividir una cadena solo por el último carácter de espacio en blanco

$str="hello this is  a space"; 
$arr=preg_split("/\s+/",$str); 
print_r($arr); 

Array ([0] => hello [1] => this [2] => is [3] => a [4] => space) 

... que se divide por todas las instancias de espacios en blanco.

¿Cómo puedo expandir esta expresión regular para dividir solo por la última instancia de espacios en blanco? Para convertirse en ...

Array ([0] => hello this is  a [1] => space) 

¡Gracias de antemano por su ayuda!

Respuesta

36

Probar:

$arr=preg_split("/\s+(?=\S*+$)/",$str); 

Editar

Una breve explicación:

El (?= ...) se llama un positivo look ahead. Por ejemplo, a(?=b) solo coincidirá con un solo 'a' si el siguiente carácter (el de la derecha) es 'b'. Tenga en cuenta que el 'b' es no una parte del partido!

El \S es solo una mano corta para el character class[^\s]. En otras palabras: coincide con un solo carácter que no sea un carácter de espacio en blanco. El + después del * hace que la clase de caracteres \Spossessive.

Finalmente, el $ indica el final de la cadena.

Para recapitular, la expresión regular completa \s+(?=\S*+$) leería en la llanura Inglés de la siguiente manera:

caracteres partido de uno o más blanco el espacio sólo cuando mirando hacia el futuro de esos caracteres de espacio en blanco cero o más caracteres distintos de los caracteres de espacio en blanco , seguido por el final de la cadena, se puede ver.

+0

Excelente, gracias, que funciona a la perfección. Solo para entender, ¿podría explicar cómo funciona la parte '(? = \ S * + $)' de esa expresión, por favor? – chattsm

+0

De nada, Martin. Ver la 'edición' para una explicación. –

+0

Eso es genial, Bart, gracias. ¡Te daría más puntos si pudiera! – chattsm

2

Esto debería funcionar:

$str="hello this is a space"; 

preg_match('~^(.*)\s+([^\s]+)$~', $str, $matches); 
$result = array($matches[1], $matches[2]); 

Usted puede hacerlo sin una expresión regular:

$parts = array_map('trim', explode(' ', $str)); 
$result = array(
    implode(' ', array_slice($parts, 0, -1)), 
    end($parts) 
); 

o

$lastSpace = strrpos($str, ' '); 
$str1 = trim(substr($str, 0, $lastSpace)); 
$str2 = trim(substr($str, $lastSpace)); 
$result = array($str1, $str2); 
+0

Gracias Tom, dos soluciones alternativas inteligentes. – chattsm

0

Si el * y + después \S dupicated? Solo /\s+(?=\S+$)/ o /\s+(?=\S*$)/ es suficiente según la necesidad.

+0

No duplicado: el '* +' es un comando único, y '\ S * +' a menudo puede ser más eficiente que hacer '\ S *'. Lea sobre "cuantificadores posesivos" para más detalles. –

Cuestiones relacionadas