Как я могу разбить строку после n-го поля и создать массив из оставшихся частей в PHP? - PullRequest
0 голосов
/ 03 мая 2018

У меня есть следующая строка:

*/3 * * * * echo yes

То, что я хочу сделать, это создать массив из двух элементов из этого, где элементы отделены после 5-го поля друг от друга:

$result = [ "*/3 * * * *", "echo yes" ];

В Linux bash shell я бы просто использовал:

echo "*/3 * * * * logger yes" | cut -d' ' -f1-5
echo "*/3 * * * * logger yes" | cut -d' ' -f6-

Как вы видите, это запись cron. Так что написание RegEx было бы довольно неудобно, так как поля могут меняться. Хорошо, я мог бы написать RegEx, который разделяет элементы друг от друга с помощью пробела, но мне интересно, есть ли какая-либо функция в PHP, которая аналогична тоже GNU cut или awk, которую я мог бы использовать для того, что разделяет две части после 5-го поля.

Как я могу достичь того же результата с PHP?

Ответы [ 3 ]

0 голосов
/ 03 мая 2018

Функции explode(), array_slice() и implode(), используемые вместе, будут работать аналогично инструменту cut.

Вы можете использовать его для разбиения строки на массив:

$line = '*/3 * * * * echo yes';

$parts = explode(' ', $line);

Затем вы можете использовать array_slice() для извлечения расписания и команды и implode() для преобразования массивов в строки:

$schedule = implode(' ', array_slice($parts, 0, 5));

$command = implode(' ', array_slice($parts, 5));

print $schedule.PHP_EOL.$command;

Покажет:

*/3 * * * *
echo yes

Попробуйте сами: https://3v4l.org/sW7VJ

0 голосов
/ 03 мая 2018

Самый первый шаг в попытке разобрать что-либо - это понять грамматику того, что вы пытаетесь разобрать. Если вы не можете определить это, то все, что вы делаете впоследствии, потерпит неудачу Предоставление только одного или двух примеров в отсутствие определения будет основанием для закрытия вашего вопроса, однако он выглядит очень похоже на файл crontab . Грамматика этого очень хорошо определена, но она работает не так, как вы думаете.

  • Поля разделены не "", а переменным количеством пробелов
  • может быть начальный пробел перед первым символом
  • всегда есть 6 полей
  • все поля могут быть переменной длины и содержать (почти) любые печатные диаграммы ASCII
  • 6-е поле может содержать встроенный и неэкранированный пробел

Ваш метод вырезания неправильно обрабатывает эту грамматику.

Вы можете разобрать его с помощью регулярного выражения:

if (preg_match('/^(\s*\S+)(\s+\S+)(\s+\S+)(\s+\S+)(\s+\S+)(\s+.+)$/', $str, $match)) {
    print_r($match);
} else {
    print "invalid";
}

Из выходных данных должно быть очевидно, как затем создать свой массив.

0 голосов
/ 03 мая 2018

Попробуйте это:

$result = [
   implode('', array_slice(explode(' ', $string), 0, 5),
   implode('', array_slice(explode(' ', $string), 5)
];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...