У меня есть большой строковый блок, который мне нужно разбить на массивы в зависимости от того, заключены ли они в скобки или разделены новыми строками.
Входные данные:
[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] => ''
)
Вы можете использовать это регулярное выражение в 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
)
Сначала сопоставьте все квадратные скобки (которые могут содержать новые строки), в противном случае — одну строку.
Причина, по которой я одобряю 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]',
)
В качестве альтернативы, чтобы изменить формулировку вашей логики, вы хотите взорваться на всех символах новой строки, которые не находятся внутри выражения в квадратных скобках. Ты можешь использовать (*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]',
)