#php #regex #preg-split
#php #регулярное выражение #preg-split
Вопрос:
У меня есть две строки:
C:UsersBobMy Documents
/Users/Bob/Documents
Мне удалось вызвать это регулярное выражение:
preg_split('/(?<=[/\])(?![/\])/', $string)
это вернет
Array
(
[0] => C:
[1] => Users
[2] => Bob
[3] => My Documents
)
Array
(
[0] => /
[1] => Users/
[2] => Bob/
[3] => Documents
)
Тем не менее, я ищу
Array
(
[0] => C:
[1] => Users
[2] => Bob
[3] => My Documents
)
Array
(
[0] => /
[1] => Users
[2] => Bob
[3] => Documents
)
т.е. Конечные косые черты отсутствуют в исправленных массивах
Комментарии:
1. Есть какая-нибудь причина, по которой вы не можете просто разделить его на
/
или` and add
DIRECTORY_SEPARATOR` до первого индекса?2. Вы можете разделить с разделителем или без него, но не с первой частью и без других частей. Пожалуйста, прочтите руководство пользователя: php.net/manual/en/function.preg-split.php
3. @Lekensteyn Я полагаю, вы имеете в виду предопределенную константу PHP? Несмотря на хороший подход, пути не имеют отношения к размещенной среде
Ответ №1:
Почему бы просто не проверить наличие «/» или «», а затем использовать explode
с соответствующим разделителем?
<?php
$s1 = 'C:\Users\Bob\My Documents';
$s2 = '/Users/Bob/Documents';
function mySplit($s) {
if(strpos($s, '/') !== false) {
$d = '/';
}elseif(strpos($s,'\') !== false) {
$d = '\';
}else {
throw new Exception('Valid delimiter not found.');
}
$ret = explode($d, $s);
$ret[0] .= $d;
return $ret;
}
echo '<pre>' . print_r(mySplit($s1),true) . '</pre>';
echo '<pre>' . print_r(mySplit($s2),true) . '</pre>';
?>
(Обновлено с немного более аккуратной версией)
Комментарии:
1. Я использовал
strpos()
вместоstrstr()
. Согласно руководству по PHP: Примечание: Если вы хотите только определить, встречается ли конкретная игла в стоге сена, вместо этого используйте более быструю и менее ресурсоемкую функцию strpos() .
Ответ №2:
С помощью следующего кода вы получите то, что хотите, но первый ключ также будет без косой черты:
preg_split('#(?<=)[/\]#', $string);
Ответ №3:
$dirs = explode(DIRECTORY_SEPARATOR, $string);
$dirs[0] .= DIRECTORY_SEPARATOR;
Комментарии:
1. Мне нравится, насколько это коротко. К сожалению, он неправильно анализирует путь в стиле Windows, когда он выполняется на компьютере с Linux (и наоборот).
2. @MarkBiek Да, но это очень редкая необходимость анализировать путь к не хост-машине. По крайней мере, по моему опыту 🙂
3. Похоже, в случае с Вантелом ему приходится анализировать пути, не связанные с хост-средой.
4. @Vanthel, вы, безусловно, можете это сделать, если уверены в своих вводных данных.
5. @Vanthel Да, это будет работать, за исключением того, что вы должны протестировать его следующим образом:
$delim = ((strpos($string, '/') !== false) ? '/' : '\')
потому что ноль тоже принимает значение false.
Ответ №4:
Я знаю, что вы уже приняли ответ, но есть очень простое, однострочное решение этой проблемы, которое я регулярно использую, и я чувствую, что его нужно опубликовать здесь:
$pathParts = explode('/', rtrim(str_replace('\', '/', $path)));
Это заменяет обратную косую черту прямой косой чертой, обрезает любые конечные косые черты и взрывается. Это можно сделать безопасно, поскольку пути Windows не могут содержать косых черт, а пути Linux не могут содержать обратных косых черт.
Результирующий массив выглядит не совсем так, как вы описали выше — корневая часть пути не будет содержать косую черту, но в любом случае он лучше представлен таким образом. Это потому, что корень пути (т. Е. C:
Или ‘/’) На самом деле не так полезен при хранении с косыми чертами. В результате этого вы можете вызвать implode('/', $pathParts);
и получить действительный обратный путь, тогда как с вашим массивом вы получите дополнительную косую черту в корне. Кроме того, UsersUserMy Documents
(без буквы диска) по-прежнему является допустимым путем в Windows, он просто подразумевает текущий рабочий объем.
Комментарии:
1. Спасибо за вклад. И отличное объяснение. Я согласен, что в большинстве случаев этот ответ более чем уместен, и я не сомневаюсь, что когда-нибудь воспользуюсь этим. Но в моем случае исходный ответ по-прежнему ближе всего к тому, что мне требуется (где полезен root, отсюда и мои усилия по его сохранению).