我知道这个问题已被无数次询问,但我无法找到适合我案例的解决方案。
我希望使用分号作为分隔符在PHP(5.3)中拆分字符串,除非它们位于$BODY$
个字符串之间。目标是拆分SQL语句,其中语句可以是过程(在本例中为postgresql)。
示例:
select; start $BODY$ begin; end; $BODY$ lang; update
应该导致:
select start $BODY$ begin; end; $BODY$ lang update
我一直在玩preg_split
一段时间,找不到合适的解决方案。
非常感谢
编辑:它必须适用于多行输入(但我可以先使用str_replace
删除换行符)
答案 0 :(得分:0)
$a = explode(';', 'select; $BODY$ begin; end; $BODY$ lang; update');
$b = array();
$index = 0;
$waiting = false;
foreach($a as $str) {
if(strpos($str,'$BODY$') !== false) {
$waiting = !$waiting;
}
$b[$index] .= $str.';';
if(!$waiting) {
$index++;
}
}
print_r($b);
这可以假设没有多个级别的嵌套$ BODY $。我觉得必须有一个可以完成的正则表达,但我的大脑目前还没有合作。
答案 1 :(得分:0)
这是一个与你的例子相符的快速模式。希望它能为您提供更灵活的方向:
$string = 'select; $BODY$ begin; end; $BODY$ lang; update';
preg_match('/^(?:(.*?);\s?)?(\$BODY\$.+?\$BODY\$[^;]+)(?:;\s?(.+?))?$/', $string, $array);
$array = array_filter($array);
$array = array_slice($array, 1, 3);
var_dump($array);
答案 2 :(得分:0)
由于似乎没有正则表达式,所以我是如何为感兴趣的人做的:
$length = strlen($sql); $queries = array(); $offset = 0; $last = 0; do { if (($colon = strpos(substr($sql, $offset), ';')) === false) { break; } $colon += $offset; if (($body = strpos(substr($sql, $offset), '$BODY$')) !== false) { $body += $offset; if ($body < $colon) { $offset = $body + strpos(substr($sql, $body + 6), '$BODY$') + 12; continue; } } $queries[] = trim(substr($sql, $last, $colon - $last)); $last = $offset = $colon + 1; } while($offset <= $length);
答案 3 :(得分:0)
这是一种更简单的方法。
$test_string = 'select; start $BODY$ begin; end; $BODY$ lang; update';
$test_string = explode('$BODY$', $test_string);
$level_flag = 1;
for ($i = 0; $i < count($test_string); $i++) {
if ($level_flag) {
$test_string[$i] = str_replace(';', "\n", $test_string[$i]);
$level_flag = 0;
} else {
$level_flag = 1;
}
}
$test_string = implode('$BODY$', $test_string);
答案 4 :(得分:0)
您自己的解决方案不适用于提供的示例。我得到的输出是:
select
start $BODY$ begin; end; $BODY$ lang
Nev Stokes的regexp的微小变化使其按要求工作:
$sql = 'select; start $BODY$ begin; end; $BODY$ lang; update';
preg_match(
'/^(?:(.*?);\s?)([^;]+\$BODY\$.+?\$BODY\$[^;]+)(?:;\s?(.+?))$/',
$sql,
$queries
);
array_shift($queries);