Строка в массив, разделенная новыми строками и скобками

У меня есть большой строковый блок, который мне нужно разбить на массивы в зависимости от того, заключены ли они в скобки или разделены новыми строками.

Входные данные:

[this is block
this is also same "block"this is same block

another same block]
new block!
another new block!
[this is new block
this is also a new block]

Одна из многих вещей, которые я пробовал:

$block_lines = preg_split('/\[([^]]+)\]|\r/', $block_content);

Ожидаемый результат:

Array
(
[0] => 'this is block
this is also same "block"this is same block

another same block'
[1] => 'new block!'
[2] => 'another new block!'
[3] => 'this is new block
this is also a new block'
)

Фактический результат:

Array
(
[0] => 'new block!'
[1] => 'another new block!'
[2] => ''
)

1

Решение

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

/\[([^]]+)]|\R/

Он разбивает строку на строку символов внутри [ а также ]или на новой строке. Используя PREG_SPLIT_DELIM_CAPTURE флаг, мы можем захватить содержимое [] также:

$string = '[this is block
this is also same "block"this is same block

another same block]
new block!
another new block!
[this is new block
this is also a new block]';
print_r(preg_split('/\[([^]]+)]|\R/', $string, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE));

Выход:

Array (
[0] => this is block
this is also same "block"this is same block

another same block
[1] => new block!
[2] => another new block!
[3] => this is new block
this is also a new block
)

Демо на 3v4l.org

2

Другие решения

Сначала сопоставьте все квадратные скобки (которые могут содержать новые строки), в противном случае — одну строку.

Причина, по которой я одобряю preg_match_all() над preg_split() в данном случае это объясняется тем, что, проще говоря, вы на самом деле не собираетесь выполнять динамические взрывы, а находить совпадения.

Код: (демонстрация)

$text = '[this is block
this is also same "block"this is same block

another same block]
new block!
another new block!
[this is new block
this is also a new block]';

var_export(preg_match_all('~\[[^\]]*]|.+~', $text, $matches) ? $matches[0] : 'nothing');

Выход:

array (
0 => '[this is block
this is also same "block"this is same block

another same block]',
1 => 'new block!',
2 => 'another new block!',
3 => '[this is new block
this is also a new block]',
)
1

В качестве альтернативы, чтобы изменить формулировку вашей логики, вы хотите взорваться на всех символах новой строки, которые не находятся внутри выражения в квадратных скобках. Ты можешь использовать (*SKIP)(*FAIL) сопоставлять и игнорировать выражения в скобках, а также разбивать все строки, проходящие через фильтр.

Код: (демонстрация)

var_export(preg_split('~\[[^\]]*](*SKIP)(*FAIL)|\R~', $text));

Выход:

array (
0 => '[this is block
this is also same "block"this is same block

another same block]',
1 => 'new block!',
2 => 'another new block!',
3 => '[this is new block
this is also a new block]',
)
0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector