Как разбить строку на элементы массива в зависимости от типа символа PHP

185
18 октября 2017, 07:46

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

Есть строка, соответствующая почтовому коду Соединенного Королевства. Необходимо разбить ее на части и сформировать из них общий массив в том же порядке, в каком они записаны в строку. Каждая часть должна соответствовать:

  • букве или нескольким буквам, идущим подряд, без чисел и других символов, в частности пробела, до первого НЕ подходящего символа

  • одной или нескольким цифрам (числу), идущим подряд, до первого НЕ подходящего символа

  • другому символу (в моем примере это исключительно один вероятный пробел, я представляю его как не буква и не цифра)

Условно, элементов массива может быть неопределенное количество, но они ограничены шаблоном почтового кода королевства. Вот картинка отлично описывающая шаблон:

Позаимствовано у www.getthedata.com

где:

  • L - буква
  • N - цифра
  • A - цифра или буква
  • SPACE - пробел
  • Отметка Optional над символом означает что он не обязательно будет присутствовать.

    1. Пример 1:

      Код SW1A 1AA должен после преобразования стать массивом со следующим набором элементов:

      [ 'SW', '1', 'A', ' ', '1', 'AA' ]
      
    2. Пример 2:

      Часть кода SW1A должна стать массивом со следующим набором элементов:

      [ 'SW', '1', 'A' ]
      
    3. Пример 3:

      Часть кода SW22 3 должна стать массивом со следующим набором элементов:

      [ 'SW', '22', ' ', '3' ]
      

Постскриптум: Особенную сложность для меня представляет то, что на части может разбиваться как целый почтовый код, так и отдельная его часть, вплоть до пустой строки. Не являясь экспертом в регулярных выражениях, эта задача мне оказалась не под силу :( Возможно есть более простое универсальное решение, чем использование функции preg_split?

Answer 1

Можно токенизировать строку следующим образом (см. онлайн-демо):

$strs = ["SW1A 1AA", "SW1A", "SW22 3"];
foreach ($strs as $s) {
  if (preg_match_all('~[a-zA-Z]+|\d+|[^\da-zA-Z]+~', $s, $chunks)) {
    print_r($chunks[0]);
  }
}
// - Array ( [0] => SW [1] => 1 [2] => A [3] =>   [4] => 1 [5] => AA )
// - Array ( [0] => SW [1] => 1 [2] => A )
// - Array ( [0] => SW [1] => 22[2] =>   [3] => 3 )

Регулярное выражение тут (см. демо)

[a-zA-Z]+|\d+|[^\da-zA-Z]+

Оно находит

  • [a-zA-Z]+ - одна или более латинских букв
  • | - или
  • \d+ - одна или более цифр
  • | - или
  • [^\da-zA-Z]+ - - один или более символов, отличных от цифр и латинских букв

Если нужна поддержка Юникода, используйте '~\p{L}+|\p{N}+|[^\p{N}\{L}]+~u'.

READ ALSO
php вывод массива из json

php вывод массива из json

сейчас я делаю вывод массива skills прямым выводом его элементов, но если в массиве элементов оказывается меньше трех - скрипт не работает, а если...

192
Как каждые 10 часов очищать файл text.txt [дубликат]

Как каждые 10 часов очищать файл text.txt [дубликат]

На данный вопрос уже ответили:

132
Как передать двойные кавычки в форму

Как передать двойные кавычки в форму

Добрый деньУ меня есть форма с текстовым полем Input В это текстовое поле отправляется значение при нажатии на кнопку

197