Как правильно разбить строку по определенному символу
Имеется строка вида: 192.168.0.1@User;p@ssword . Мне нужно положить в массив отдельно 192.168.0.1, User и p@ssword, чтобы пользоваться этими данными по отдельности. Дело в том, что, если запись будет в таком виде — 192.168.0.1@User;password , то мне удается получить значения через этот код:
$data = explode("@", "192.168.0.1@User;password"); $data2= explode(";", $data[1]);
В итоге я пользуюсь всеми тремя значениями:
$data[0] (192.168.0.1) $data2[0] (User) $data2[1] (password)
Получается, что проблема возникает, когда в строке два символа — @. Помогите, пожалуйста, разобраться.
PHP разбить строку по символу с исключением
Есть к примеру такая строка 123|@rand(тест <@rand(номер 1234|номер 4321)>|строка|| . Это строка параметров функции в тексте. (функция выглядит, как ). Каждый параметр отделяется знаком | И мне нужно получить из этой строки массив с параметрами. Т.е. разбить строку по символу | . Главная проблема в том, что в строке может содержаться вызов функции с такой же строкой параметров, в которой тоже содержится знак | . Отдельный вызов функции НЕЛЬЗЯ ДЕЛИТЬ! Итого нужно разбить строку выше на такой массив
array( 123, '@rand(тест <@rand(номер 1234|номер 4321)>', строка, '', // || считать, как пустая строка '' );
Помогите составить регулярное выражение! Я накидал что-то такое, но это работает неправильно — «/[^(<@\w+\()]\|[^(\)>)]/ui
Отслеживать
задан 14 ноя 2021 в 13:32
582 4 4 серебряных знака 19 19 бронзовых знаков
Почему не передать нужные параметры в виде json?
14 ноя 2021 в 17:41
я пишу бота, который генерирует ответ по словарю json. Словарь огромный будет. В нем, чтобы каждая фраза была бы более уникальной, я использую функции — Привет, <@rand(я Гриша|я Григорий|я Григорий, а ты дурак)>
14 ноя 2021 в 17:46
Я бы предложил создать файл с массивами переменных уникальных фраз. Более читабельно. А в вызове
14 ноя 2021 в 23:21
Где name — имя переменной с массивов уникальных значений
14 ноя 2021 в 23:22
@Николай — такая реализация есть — (@name) вместо подставляется случайное значение из списка name. Но создавать сотни таких переменных — идиотизм
16 ноя 2021 в 13:22
2 ответа 2
Сортировка: Сброс на вариант по умолчанию
preg_split('~(?![^|])(*SKIP)(*F)|\|~u', $text)
- \w+ — одна и более букв, цифр или знак _
- \( — символ (
- .*? — ноль или более символов, отличных от символа перевода строки, как можно меньше
- \)> — текст )>
- (?![^|]) — сразу после текущей позиции должен быть символ | или конец строки
- (*SKIP)(*F) — в текущей позиции сигнализирует конец совпадения, которое отменяется, а поиск нового совпадения начинается именно с текущей позиции
- | — или
- \| — символ | .
$text = "123|@rand(тест <@rand(номер 1234|номер 4321)>|строка||"; print_r(preg_split('~(?![^|])(*SKIP)(*F)|\|~u', $text));
Array ( [0] => 123 [1] => @rand(тест <@rand(номер 1234|номер 4321)>[2] => строка [3] => [4] => )
Отслеживать
ответ дан 14 ноя 2021 в 23:25
Wiktor Stribiżew Wiktor Stribiżew
21.2k 3 3 золотых знака 24 24 серебряных знака 49 49 бронзовых знаков
Не работает для строки 123|1231|41245 или hi||bye .@rand(1|2)>
15 ноя 2021 в 13:11
15 ноя 2021 в 13:15
Гм, странно, в онлайн компиляторе (sandbox.onlinephpfunctions.com) ваше выражение разбило параметры в @rand. Онлайн тестер регулярок показывает все слеши, но только в случае, если в строке один вызов функции. Не работает для 123|3424|14|||
15 ноя 2021 в 13:36
Хах, кажется заработало, спасибо. Я еще протестирую и помечу, как правильный
15 ноя 2021 в 13:38
Блин, другая проблема появилась. Нужна регулярка, которая будет искать несколько строк с параметрами в строке типа строка с <@rand(1|<@rand(2|3|<@rand(4|5)>)>)> и <@rand(1|<@rand(2|3|<@rand(4|5)>)>)> Я написал такую регулярку /<@(?
15 ноя 2021 в 17:26
В свете более подробного разъяснения автором задачи, я бы предложил новое решение.
//Во-первых в приведенном примере автор немного ошибся и забыл у первого `@rand` в конце закрывающую скобку я ее добавил, если это не так - поправьте строку ну и регулярку $text = "123|@rand(тест <@rand(номер 1234|номер 4321)>)|строка||"; //Разбитие по `|` приведет к тому, что Вы в выходном массиве получите еще и разбитые параметры функции `@rand`. Что как Вы сами пишите и является проблемой которую Вам в том числе нужно решить //Поэтому я бы сделал так. В строке которая содержит параметры `@rand(тест <@rand(номер 1234|номер 4321)>)` вначале заменил `|` на какой-то другой символ. if ( preg_match_all("/(@(\S+)\((.*)\))/", $text, $matches) && is_array( $matches ) && count($matches) > 0 && is_array($matches[0]) && count($matches[0]) > 0) < //Меняем `|` на `&` $rtext = preg_replace("/\|/", "&", $matches[0][0]); //preg_quotes экранирует спец.символы использующиеся в регулярных выражениях - а их у нас в полученной строке полно $text = preg_replace("/".preg_quote($matches[0][0])."/", $rtext, $text); //После чего спокойно разбил всю исходную строку `$text`, по символу `|` $params = explode("|", $text); if ( is_array( $params ) && count( $params ) >0 ) < //Далее идем по массиву и ищем элемент-строку начинающийся на '@' foreach( $params as $p ) < $p = trim( $p ); if ( mb_substr( $p, 0, 1) == '@' ) < //@rand(тест <@rand(номер 1234&номер 4321)>) //А теперь парсим эту строку на содержание параметров //Если кол-во параметров другое или формат строки отличается - подправьте регулярку if ( preg_match_all("/^\@\S+\(\W+\\)/", $p, $matches) && is_array( $matches ) && count($matches) > 0 && is_array($matches[0]) && count($matches[0]) > 0) < $param1 = $matches[1][0]."\n"; //номер 1234 $param2 = $matches[2][0]."\n"; //номер 4321 >> > > >
explode
Функция возвращает массив строк, каждая из которых — подстрока, которая образовалась за счёт разделения строки string по границам, которые образовала строка-разделитель separator .
Список параметров
Функция вернёт массив, который будет содержать максимум limit элементов, при этом последний элемент будет содержать остаток строки string .
Функция вернёт все компоненты за вычетом заданного в параметре limit количества элементов с конца, если параметр limit отрицательный.
Функция расценит значение limit как 1, если параметр равен нулю.
Замечание:
До PHP 8.0 функция implode() принимала параметры в любом порядке. Функция explode() никогда этого не поддерживала: убедитесь, что разделитель separator идёт перед строкой string .
Возвращаемые значения
Функция возвращает массив ( array ) строк ( string ), который она создаёт разделением строки string по границам, которые образовал разделитель separator .
Функция explode() выбрасывает исключение ValueError , если разделитель separator — пустая строка «». Функция возвращает пустой массив ( array ), если разделителя separator нет в строке string и задали отрицательное значение параметра limit , иначе возвращает массив, который содержит строку string . Функция добавит значения как пустые значения массива ( array ) в первой или в последней позиции массива ( array ), который она возвращает, если значения разделителя separator появляются в начале или в конце строки string , соответственно.
Список изменений
| Версия | Описание |
|---|---|
| 8.0.0 | Теперь функция explode() выбрасывает исключение TypeError , если разделитель separator — пустая строка «» . Раньше функция explode() вместо исключения возвращала false . |
Примеры
Пример #1 Пример использования функции explode()
// Пример 1
$pizza = «кусок1 кусок2 кусок3 кусок4 кусок5 кусок6» ;
$pieces = explode ( » » , $pizza );
echo $pieces [ 0 ]; // кусок1
echo $pieces [ 1 ]; // кусок2
// Пример 2
$data = «foo:*:1023:1000::/home/foo:/bin/sh» ;
list( $user , $pass , $uid , $gid , $gecos , $home , $shell ) = explode ( «:» , $data );
echo $user ; // foo
echo $pass ; // *
Пример #2 Пример значения, которое возвращает функция explode()
/**
* Строка, которая не содержит разделителя, будет
* просто возвращать массив с одним значением оригинальной строки.
*/
$input1 = «hello» ;
$input2 = «hello,there» ;
$input3 = ‘,’ ;
var_dump ( explode ( ‘,’ , $input1 ) );
var_dump ( explode ( ‘,’ , $input2 ) );
var_dump ( explode ( ‘,’ , $input3 ) );
Результат выполнения приведённого примера:
array(1) ( [0] => string(5) "hello" ) array(2) ( [0] => string(5) "hello" [1] => string(5) "there" ) array(2) ( [0] => string(0) "" [1] => string(0) "" )
Пример #3 Примеры работы функции с параметром limit
// положительный лимит
print_r ( explode ( ‘|’ , $str , 2 ));
// отрицательный лимит
print_r ( explode ( ‘|’ , $str , — 1 ));
Результат выполнения приведённого примера:
Array ( [0] => один [1] => два|три|четыре ) Array ( [0] => один [1] => два [2] => три )
Примечания
Замечание: Эта функция безопасна для обработки данных в двоичной форме.
Смотрите также
- preg_split() — Разбивает строку по регулярному выражению
- str_split() — Преобразовывает строку в массив
- mb_split() — Разделяет строки в многобайтных кодировках через регулярное выражение
- str_word_count() — Возвращает информацию о словах, входящих в строку
- strtok() — Разбивает строку на токены
- implode() — Объединяет элементы массива в строку
Improve This Page
User Contributed Notes 4 notes
2 years ago
Note that an empty input string will still result in one element in the output array. This is something to remember when you are processing unknown input.
For example, maybe you are splitting part of a URI by forward slashes (like «articles/42/show» => [«articles», «42», «show»]). And maybe you expect that an empty URI will result in an empty array («» => []). Instead, it will contain one element, with an empty string:
$uri = » ;
$parts = explode ( ‘/’ , $uri );
var_dump ( $parts );
5 months ago
If your data is smaller than the expected count with the list expansion:
$data = «foo:*:1023:1000::/home/foo:/bin/sh» ;
list( $user , $pass , $uid , $gid , $gecos , $home , $shell , $nu ) = explode ( «:» , $data );
?>
The result is a warning not an error:
PHP Warning: Undefined array key 7 in .
The solution is to pad the array to the expected length:
$data = «foo:*:1023:1000::/home/foo:/bin/sh» ;
list( $user , $pass , $uid , $gid , $gecos , $home , $shell , $nu ) = array_pad ( explode ( «:» , $data ), 8 , «» );
// where 8 is the count of the list arguments
?>
3 years ago
Be careful, while most non-alphanumeric data types as input strings return an array with an empty string when used with a valid separator, true returns an array with the string «1»!
var_dump(explode(‘,’, null)); //array(1) < [0]=>string(0) «» >
var_dump(explode(‘,’, false)); //array(1) < [0]=>string(0) «» >
var_dump(explode(‘,’, true)); //array(1) < [0]=>string(1) «1» >
1 year ago
If you want to directly take a specific value without having to store it in another variable, you can implement the following:
echo $status_only = explode(‘-‘, $status)[0];
- Copyright © 2001-2024 The PHP Group
- My PHP.net
- Contact
- Other PHP.net sites
- Privacy policy
trim
Можно также задать список символов для удаления с помощью необязательного аргумента characters . Просто перечислите все символы, которые вы хотите удалить. Можно указать конструкцию .. для обозначения диапазона символов.
Возвращаемые значения
Примеры
Пример #1 Пример использования trim()
$text = «\t\tThese are a few words 🙂 . » ;
$binary = «\x09Example string\x0A» ;
$hello = «Hello World» ;
var_dump ( $text , $binary , $hello );
$trimmed = trim ( $text );
var_dump ( $trimmed );
$trimmed = trim ( $text , » \t.» );
var_dump ( $trimmed );
$trimmed = trim ( $hello , «Hdle» );
var_dump ( $trimmed );
$trimmed = trim ( $hello , ‘HdWr’ );
var_dump ( $trimmed );
// удаляем управляющие ASCII-символы с начала и конца $binary
// (от 0 до 31 включительно)
$clean = trim ( $binary , «\x00..\x1F» );
var_dump ( $clean );
Результат выполнения приведённого примера:
string(32) " These are a few words :) . " string(16) " Example string " string(11) "Hello World" string(28) "These are a few words :) . " string(24) "These are a few words :)" string(5) "o Wor" string(9) "ello Worl" string(14) "Example string"
Пример #2 Обрезание значений массива с помощью trim()
$fruit = array( ‘apple’ , ‘banana ‘ , ‘ cranberry ‘ );
var_dump ( $fruit );
array_walk ( $fruit , ‘trim_value’ );
var_dump ( $fruit );
Результат выполнения приведённого примера:
array(3) < [0]=>string(5) "apple" [1]=> string(7) "banana " [2]=> string(11) " cranberry " > array(3) < [0]=>string(5) "apple" [1]=> string(6) "banana" [2]=> string(9) "cranberry" >
Примечания
Замечание: Возможные трюки: удаление символов из середины строки
Так как trim() удаляет символы с начала и конца строки string , то удаление (или не удаление) символов из середины строки может ввести в недоумение. trim(‘abc’, ‘bad’) удалит как ‘a’, так и ‘b’, потому что удаление ‘a’ сдвинет ‘b’ к началу строки, что также позволит её удалить. Вот почему это «работает», тогда как trim(‘abc’, ‘b’) очевидно нет.
Смотрите также
- ltrim() — Удаляет пробелы (или другие символы) из начала строки
- rtrim() — Удаляет пробелы (или другие символы) из конца строки
- str_replace() — Заменяет вхождения строки поиска строкой замены