我试图通过竖线爆炸一个字符串。这很容易。但是,我不希望拆分影响括号括起来的子串。这意味着我需要一个字符串,如:
Hello (sir|maam).|Hi there!
爆炸成:
Array
(
[0] => Hello (sir|maam).
[1] => Hi there!
)
通过使用普通爆炸功能,我不相信有一种方法可以告诉它忽略圆括号所包围的条形。但是,我有一些想法。
我知道可以通过正常爆炸字符串,然后循环遍历数组并将包含(
的字符串之间的所有内容合并到包含)
的结束字符串来实现此目的。但是,我觉得应该有更优雅的方式实现这一目标。
我是对的吗?在给定这些限制的情况下,是否存在代码密集度较低的将字符串拆分为数组的方法?
答案 0 :(得分:3)
如果你能保证括号是平衡的而且从不嵌套(也就是说,如果永远不会有'Oops(!'
或'(nested stuff (like this)|oops)'
),那么永远不会有||
在你想要匹配为空字符串的括号之外,这应该有所帮助:
preg_match_all('/(?:[^(|]|\([^)]*\))+/', $your_string, $matches);
$parts = $matches[0];
它会匹配[一个不是|
或(
的字符),或一个(
和)
包围任何不是{{1}的内容}(包括)
)],尽可能多次(但至少一次)。简短版本:它会在匹配的括号之间设置|
,而不是分隔符。
另一种可能性,即稍微不那么神秘:
|
如果中间没有$parts = preg_split('/\|(?![^(]*\))/', $your_string);
,则使用先行断言来取消|
之后)
所有{{}}}的资格。 parens仍然有点无情,但它会匹配两个(
之间的空字符串。
答案 1 :(得分:0)
直到有人写一个基于正则表达式的解决方案,我怀疑单次传递是否可行,这应该有效。它是对代码的直接需求翻译。
<?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));