Php 拆分字符串,除非包含在其他字符串之间
我知道这个问题被问了无数次,但我找不到一个有效的解决方案 我想在PHP(5.3)中使用分号作为分隔符拆分字符串,除非它们位于Php 拆分字符串,除非包含在其他字符串之间,php,sql,Php,Sql,我知道这个问题被问了无数次,但我找不到一个有效的解决方案 我想在PHP(5.3)中使用分号作为分隔符拆分字符串,除非它们位于$BODY$字符串之间。目标是拆分SQL语句,其中语句可以是过程(本例中为postgresql) 例如: select; start $BODY$ begin; end; $BODY$ lang; update 选择;start$BODY$begin;结束$BODY$lang;更新 应导致: select start $BODY$ begin; end; $BODY$ la
$BODY$
字符串之间。目标是拆分SQL语句,其中语句可以是过程(本例中为postgresql)
例如:
select; start $BODY$ begin; end; $BODY$ lang; update
选择;start$BODY$begin;结束$BODY$lang;更新
应导致:
select
start $BODY$ begin; end; $BODY$ lang
update
选择
start$BODY$begin;结束$BODY$lang
更新
我一直在玩弄preg_split
有一段时间了,找不到有效的解决方案
非常感谢
编辑:它必须适用于多行输入(但我可以使用str\u replace
手动删除换行符)
假设没有多个嵌套的$BODY$级别,这将起作用。我觉得必须有一个正则表达式才能完成,但我的大脑目前不合作。这里有一个与您的示例相匹配的快速模式。希望它能为您指明更灵活的方向:
$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);
由于没有合适的正则表达式,下面是我为感兴趣的人所做的: $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); $length=strlen($sql); $querys=array(); $offset=0; $last=0; 做{ if($colon=strpos(substr($sql,$offset),“;”)==false){ 打破 } $colon+=$offset; if($body=strpos(substr($sql,$offset),“$body$”)!==false){ $body+=$offset; if($body<$colon){ $offset=$body+strop(substr($sql,$body+6),“$body$”)+12; 继续; } } $querys[]=trim(substr($sql,$last,$colon-$last)); $last=$offset=$colon+1; }而($offset这里有一个更简单的方法
$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);
$test_string='select;start$BODY$begin;end;$BODY$lang;update';
$test_string=分解($BODY$,$test_string);
$level_标志=1;
对于($i=0;$i
您自己的解决方案与提供的示例不兼容。我得到的结果是:
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);
给出一个更简单的例子,更多的文本输入和预期的输出结果。否则人们会建议编写解析器。完成,谢谢你的评论。我忘了提到$BODY$标记前面有一些文本破坏了regexp。我更新了这个例子。无论如何,谢谢!
$sql = 'select; start $BODY$ begin; end; $BODY$ lang; update';
preg_match(
'/^(?:(.*?);\s?)([^;]+\$BODY\$.+?\$BODY\$[^;]+)(?:;\s?(.+?))$/',
$sql,
$queries
);
array_shift($queries);