2009-10-07 1 views
11

надеюсь, что это должно быть быстрым и простым, используя PHP. Я пытаюсь разбить строку на массив, но только на последний экземпляр пробела. До сих пор у меня есть ...Regex для разделения строки только на последний пробельный символ

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

... который разбивается на все экземпляры пробелов.

Как я могу расширить это регулярное выражение, чтобы разделить только последний экземпляр пробелов? Чтобы стать ...

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

Благодарим вас за помощь!

ответ

36

Try:

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

Редактировать

Краткое объяснение:

(?= ...) называется положительным look ahead. Например, a(?=b) будет соответствовать только одному 'a', если следующий символ (один справа от него) является 'b'. Учтите, что 'b': не часть матча!

\S всего лишь короткая рука для character class[^\s]. Другими словами: он соответствует одному символу, отличному от символа пробела. + после * делает класс символов \Spossessive.

И, наконец, $ обозначает конец строки.

Напомним, что полное регулярное выражение \s+(?=\S*+$) прочитал бы на простом английском языке следующим образом:

матч один или несколько пробельных символов, только если смотреть вперед тех пробельных символов, отличных от пробельных символов ноль или более символов , за которым следует конец строки, можно увидеть.

+0

Отлично, спасибо, что отлично работает. Просто для понимания, не могли бы вы объяснить, как работает часть (? = \ S * + $) 'этого выражения? – chattsm

+0

Добро пожаловать, Мартин. См. «Edit» для объяснения. –

+0

Это замечательно Барт, спасибо. Я бы дал вам больше очков, если бы мог! – chattsm

2

Это должно работать:

$str="hello this is a space"; 

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

Вы могли бы сделать это без регулярных выражений:

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

или

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

Спасибо Том, два умных альтернативных решения. – chattsm

0

Если * и + после \S dupicated? Только /\s+(?=\S+$)/ или /\s+(?=\S*$)/ достаточно, зависит от необходимости.

+0

Не дублируется - '* +' - это одна команда, а '\ S * +' часто может быть более эффективной, чем '' S *. Подробнее читайте в разделе «Притяжательные квантификаторы». –