Preg 在 PHP 中用分号分割多条 SQL

问题描述 投票:0回答:1

我正在尝试通过 preg 拆分我的多 SQL,但它不起作用......

代码:

$multiSql = "
ALTER TABLE `my_table` CHANGE `typ` `typ` INT(10) UNSIGNED NOT NULL DEFAULT '0' COMMENT '0=none; 1=test1; 2=test2; 3=test3';

ALTER TABLE `my_table2`
  ADD `date` varchar(25) COLLATE utf8_czech_ci DEFAULT NULL AFTER `test`;
 
ALTER TABLE `my_table3` ADD `date` varchar(25) COLLATE utf8_czech_ci DEFAULT NULL AFTER `test`; ALTER TABLE `my_table3` ADD `test2` varchar(25) COLLATE utf8_czech_ci DEFAULT NULL AFTER `date`;

ALTER TABLE `my_table3` CHANGE `test2` `test2` INT(10) UNSIGNED NOT NULL DEFAULT '0' COMMENT '0=test; 1=test2;';
";

$sqlArray = preg_split('~\([^)]*\)(*SKIP)(*FAIL)(*F)|(?<=;)(?![ ]*$)~', trim($multiSql), -1, PREG_SPLIT_NO_EMPTY);

print_r($sqlArray);

演示: https://ideone.com/nkvloT

我需要这样的输出:

1. ALTER TABLE `my_table` CHANGE `typ` `typ` INT(10) UNSIGNED NOT NULL DEFAULT '0' COMMENT '0=none; 1=test1; 2=test2; 3=test3';
2. ALTER TABLE `my_table2` ADD `date` varchar(25) COLLATE utf8_czech_ci DEFAULT NULL AFTER `test`;
3. ALTER TABLE `my_table3` ADD `date` varchar(25) COLLATE utf8_czech_ci DEFAULT NULL AFTER `test`;
4. ALTER TABLE `my_table3` ADD `test2` varchar(25) COLLATE utf8_czech_ci DEFAULT NULL AFTER `date`;
5. ALTER TABLE `my_table3` CHANGE `test2` `test2` INT(10) UNSIGNED NOT NULL DEFAULT '0' COMMENT '0=test; 1=test2;';

我正在使用不同答案中的这种模式:

~\([^)]*\)(*SKIP)(*FAIL)(*F)|(?<=;)(?![ ]*$)~
但它不适用于我的代码。

感谢您的帮助。

php sql split preg-split
1个回答
1
投票

可以使用正向前瞻来编写该模式,断言空白字符直到字符串末尾。

您也可以只使用这两种符号之一

(*FAIL)(*F)
而不是同时使用。

\([^)]*\)(*SKIP)(*F)|(?<=;)(?=\h*$|\s*\bALTER TABLE\b)

正则表达式演示 | PHP 演示

示例

$multiSql = "
ALTER TABLE `my_table` CHANGE `typ` `typ` INT(10) UNSIGNED NOT NULL DEFAULT '0' COMMENT '0=none; 1=test1; 2=test2; 3=test3';

ALTER TABLE `my_table2`
  ADD `date` varchar(25) COLLATE utf8_czech_ci DEFAULT NULL AFTER `test`;
 
ALTER TABLE `my_table3` ADD `date` varchar(25) COLLATE utf8_czech_ci DEFAULT NULL AFTER `test`; ALTER TABLE `my_table3` ADD `test2` varchar(25) COLLATE utf8_czech_ci DEFAULT NULL AFTER `date`;

ALTER TABLE `my_table3` CHANGE `test2` `test2` INT(10) UNSIGNED NOT NULL DEFAULT '0' COMMENT '0=test; 1=test2;';
";

$sqlArray = array_map(function($x){
    return trim(preg_replace("/\R/", '', $x));
}, preg_split('~\([^)]*\)(*SKIP)(*F)|(?<=;)(?=\h*$|\s*\bALTER TABLE)~m', trim($multiSql), -1, PREG_SPLIT_NO_EMPTY));

print_r($sqlArray);

输出

Array
(
    [0] => ALTER TABLE `my_table` CHANGE `typ` `typ` INT(10) UNSIGNED NOT NULL DEFAULT '0' COMMENT '0=none; 1=test1; 2=test2; 3=test3';
    [1] => ALTER TABLE `my_table2`  ADD `date` varchar(25) COLLATE utf8_czech_ci DEFAULT NULL AFTER `test`;
    [2] => ALTER TABLE `my_table3` ADD `date` varchar(25) COLLATE utf8_czech_ci DEFAULT NULL AFTER `test`;
    [3] => ALTER TABLE `my_table3` ADD `test2` varchar(25) COLLATE utf8_czech_ci DEFAULT NULL AFTER `date`;
    [4] => ALTER TABLE `my_table3` CHANGE `test2` `test2` INT(10) UNSIGNED NOT NULL DEFAULT '0' COMMENT '0=test; 1=test2;';
)
© www.soinside.com 2019 - 2024. All rights reserved.