Я пытаюсь взорвать строку по вертикальным барам. Это легкая часть. Тем не менее, я НЕ хочу, чтобы раскол влиял на подстроки, окруженные скобками. Это означает, что мне нужна строка, такая как:
Hello (sir|maam).|Hi there!
взорваться:
Array ( [0] => Hello (sir|maam). [1] => Hi there! )
Используя обычную функцию разрыва, я не верю, что есть способ сказать ей игнорировать этот бар, окруженный скобками. Однако у меня есть некоторые идеи.
Я знаю, что это можно было бы сделать, просто взорвав строку, а затем перейдя через массив и объединив все между строками, которые содержат (
к закрывающей строке, которая содержит )
. Тем не менее, я чувствую, что должен быть более элегантный способ достижения этого.
Я прав? Есть ли менее интенсивные кодовые средства для разделения строки на массив с учетом этих ограничений?
Если вы можете гарантировать, что скобки будут сбалансированы и никогда не вложены (то есть, если никогда не будет 'Oops(!'
Или '(nested stuff (like this)|oops)'
, и никогда не будет ||
вне круглых скобок, которые вы хотите сопоставить как пустую строку, тогда это должно помочь:
preg_match_all('/(?:[^(|]|\([^)]*\))+/', $your_string, $matches); $parts = $matches[0];
Он будет соответствовать [либо (символ, который не является |
или (
), либо (
и )
охватывающий все, что не является )
(который включает |
)], сколько раз (возможно, хотя бы один раз). Короткая версия: это сделает |
между скобками части матча, а не разделителем.
Другая возможность, которая немного менее загадочна:
$parts = preg_split('/\|(?![^(]*\))/', $your_string);
Использует предварительное утверждение о дисквалификации любых |
за ним следует a )
если нет (
в промежутке между ними. Все еще немного неумолимо о parens, но он будет соответствовать пустым строкам между двумя |
s.
Пока кто-то не напишет решение на основе регулярного выражения, которое, я сомневаюсь, возможно за один проход, это должно сработать. Это простой перевод требований к коду.
<?php function my_explode($str) { $ret = array(); $in_parenths = 0; $pos = 0; for($i=0;$i<strlen($str);$i++) { $c = $str[$i]; if($c == '|' && !$in_parenths) { $ret[] = substr($str, $pos, $i-$pos); $pos = $i+1; } elseif($c == '(') $in_parenths++; elseif($c == ')') $in_parenths--; } if($pos > 0) $ret[] = substr($str, $pos); return $ret; } $str = "My|Hello (sir|maam).|Hi there!"; var_dump(my_explode($str));