2009-10-07 10 views
11

si spera che questo dovrebbe essere veloce e semplice, usando PHP sto provando a dividere una stringa in un array ma solo dall'ultima istanza di spazi bianchi. Finora ho ...Regex per dividere una stringa solo dall'ultimo carattere di spaziatura

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

... che si divide in tutte le istanze di spazio bianco.

Come è possibile espandere questa espressione regolare per dividere solo l'ultima istanza di spazi bianchi? Per diventare ...

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

Grazie in anticipo del vostro aiuto!

risposta

36

Prova:

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

Modifica

Una breve spiegazione:

Il (?= ...) è chiamato positivo look ahead. Ad esempio, a(?=b) corrisponderà a un singolo 'a' se il carattere successivo (quello a destra di esso) è un 'b'. Si noti che il 'b' è non una parte della partita!

Il \S è solo una mano breve per il character class[^\s]. In altre parole: corrisponde a un singolo carattere diverso da un carattere di spazio bianco. Il + dopo il * rende la classe di carattere \Spossessive.

Infine, lo $ indica la fine della stringa.

Per ricapitolare, la regex completa \s+(?=\S*+$) avrebbe letto in parole povere come segue:

personaggi partita uno o più spazio bianco solo quando guardando avanti di quei caratteri di spazio bianco zero o più caratteri diversi da spazi vuoti , seguito dalla fine della stringa, può essere visto.

+0

Eccellente, grazie, funziona perfettamente. Solo per la comprensione, potresti spiegare come la parte '(? = \ S * + $)' di quell'espressione funziona per favore? – chattsm

+0

Prego Martin. Vedi la 'modifica' per una spiegazione. –

+0

Questo è un grande Bart, grazie. Ti darei più punti se potessi! – chattsm

2

Questo dovrebbe funzionare:

$str="hello this is a space"; 

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

si potesse fare senza un regex:

$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

Grazie Tom, due soluzioni alternative intelligenti. – chattsm

0

Se la * e + dopo \S dupicated? Solo /\s+(?=\S+$)/ o /\s+(?=\S*$)/ è sufficiente dipende dalla necessità.

+0

Non duplicato - '* +' è un singolo comando, e '\ S * +' può essere spesso più efficiente di fare '\ S *'. Leggi su "quantificatori possessivi" per maggiori dettagli. –

Problemi correlati