Использование простого регулярного выражения через preg_match_all
и array_combine
часто является самым коротким и быстрым вариантом:
preg_match_all("/([^\\\\]+)\\\\([^\\\\]+)/", $string, $p);
$array = array_combine($p[1], $p[2]);
Теперь это, конечно, особый случай. Обе клавиши и значения разделены обратной косой чертой \ , как и все их пары. Регулярное выражение также немного длиннее из-за необходимости двойного экранирования.
Однако эту схему можно обобщить для других строк key:value,
.
Отдельные key:value,
разделители
Обычные варианты включают : и = в качестве разделителей ключа / значения, а также , или & и другие в качестве разделителей пар. В таких случаях регулярное выражение становится достаточно очевидным (с флагом /x
для удобства чтения):
# ↓ ↓ ↓
preg_match_all("/ ([^:]+) : ([^,]+) /x", $string, $p);
$array = array_combine($p[1], $p[2]);
Что делает супер легким обмен :
и ,
на другие разделители.
- Знаки равенства
=
вместо :
двоеточия.
- Например,
\\t
как разделитель пар (разделенный табуляцией ключ: списки значений)
- Классический
&
или ;
в качестве разделителя между парами ключ = значение.
- Или просто
\\s
пробелы или \\n
переводы строк даже.
Разрешить различные разделители
Вы можете сделать его более гибким / прощающим, разрешив разные разделители между ключами / значениями / парами:
# ↓ ↓ ↓
preg_match_all("/ ([^:=]+) [:=]+ ([^,+&]+) /x", $string, $p);
Где оба key=value,key2:value2++key3==value3
будут работать. Что может иметь смысл для большего количества людей, дружественных (АКА нетехнических пользователей).
Ограничить буквенно-цифровые клавиши
Часто вы можете запретить что-либо, кроме классических key
идентификаторов. Просто используйте шаблон строки слова \w+
, чтобы регулярное выражение пропускало нежелательные случаи:
# ↓ ↓ ↓
preg_match_all("/ (\w+) = ([^,]+) /x", $string, $p);
Это самый тривиальный подход к созданию белого списка. Если OTOH вы хотите заявить / заранее ограничить всю строку ключ / значение, то создайте отдельную preg_match("/^(\w+=[^,]+(,|$))+/", …
Пробелы в скобках или цитирование
Вы можете пропустить несколько шагов постобработки (например, trim
для ключей и значений) с небольшим добавлением:
preg_match_all("/ \s*([^=]+) \s*=\s* ([^,]+) (?<!\s) /x", $string, $p);
Или, например, необязательные кавычки:
preg_match_all("/ \s*([^=]+) \s*=\s* '? ([^,]+) (?<![\s']) /x", $string, $p);
INI-стиль извлечения
И вы можете создать базовый метод извлечения INI-файла:
preg_match_all("/^ \s*(\w+) \s*=\s* ['\"]?(.+?)['\"]? \s* $/xm", $string, $p);
Обратите внимание, что это всего лишь сырое подмножество распространенных схем INI.
Если у вас уже есть строка key=value&key2=value2
, то parse_str
работает как брелок. Но, комбинируя его с strtr
, можно даже обрабатывать различные другие разделители:
# ↓↓ ↑↑
parse_str(strtr($string, ":,", "=&"), $pairs);
У которого есть пара плюсов и минусов собственных:
- Даже короче, чем метод регулярных выражений с двумя строками.
- Предопределяет хорошо известный механизм экранирования, такой как
%2F
для специальных символов).
- Не допускает использование разделителей или неэкранированных разделителей внутри.
- Автоматически преобразует
keys[]=
в массивы, которые вы можете или не можете хотеть.
Альтернатива: explode
+ foreach
Вы найдете много примеров ручного расширения ключа / строки значения . Хотя это часто больше кода. explode
несколько чрезмерно используется в PHP из-за предположений об оптимизации. Однако после профилирования оно оказывается медленнее из-за руководства foreach
и коллекции массивов.