2009-10-07 12 views
11

Mam nadzieję, że powinno to być szybkie i proste, używając PHP Próbuję podzielić ciąg znaków na tablicę, ale tylko na ostatnią instancję białych znaków. Do tej pory mam ...Regex, aby podzielić ciąg tylko ostatnim znakiem odstępu.

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

... który dzieli się na wszystkie przypadki białych znaków.

Jak mogę rozwinąć to wyrażenie regularne, aby podzielić je tylko na ostatnią instancję białych znaków? Aby zostać ...

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

Z góry dziękujemy za pomoc!

Odpowiedz

36

Spróbuj:

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

Edit

Krótkie wyjaśnienie:

(?= ...) nazywa pozytywna look ahead. Na przykład a(?=b) będzie pasował tylko do pojedynczego 'a', jeśli następny znak (ten po prawej stronie) to 'b'. Zauważ, że 'b' jest nie część meczu!

The \S jest krótką ręką dla character class[^\s]. Innymi słowy: pasuje do pojedynczego znaku innego niż znak spacji. Model + po * tworzy klasę znaków \Spossessive.

Wreszcie, $ oznacza koniec napisu.

Przypomnę, kompletny regex \s+(?=\S*+$) będzie czytać w prostym języku angielskim, co następuje:

znaków mecz jeden lub więcej białej przestrzeni tylko wtedy, gdy patrząc w przyszłość z tych białych znaków zero lub więcej znaków innych niż białych znaków , a następnie koniec struny, można zobaczyć.

+0

Doskonale, dziękuję, to działa idealnie. Czy możesz wyjaśnić, jak działa część "(? = \ S * + $)" tego wyrażenia? – chattsm

+0

Nie ma za co Martin. Zobacz "edytuj", aby uzyskać wyjaśnienie. –

+0

To świetnie Bart, dziękuję. Dałbym ci więcej punktów, gdybym mógł! – chattsm

2

To powinno działać:

$str="hello this is a space"; 

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

Można to zrobić bez regex:

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

lub

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

Dzięki Tom, dwa sprytne rozwiązania alternatywne. – chattsm

0

Jeżeli * i + po \S dupicated? Tylko /\s+(?=\S+$)/ lub /\s+(?=\S*$)/ wystarczy, zależy od potrzeby.

+0

Nie powielone - '* +' jest pojedynczym poleceniem, a '\ S * +' często może być wydajniejsze niż wykonanie '\ S *'. Czytaj więcej o "kwantywie dzierżawczej", aby uzyskać więcej informacji. –

Powiązane problemy