用分号(但不在引号内)拆分php中的sql语句
我有一个系统,当用户在自由格式字段中使用分号时会导致错误。我将其追溯到一个简单的爆炸声明:用分号(但不在引号内)拆分php中的sql语句,php,regex,split,quotes,Php,Regex,Split,Quotes,我有一个系统,当用户在自由格式字段中使用分号时会导致错误。我将其追溯到一个简单的爆炸声明: $array = explode( ";", $sql ); 因为这一行是在一个从整个系统调用的子程序中,所以我想用一个可以正确分割事物的东西来替换这一行,而不会破坏系统的其余部分。我以为我会用str_getcsv成为赢家,但这也不够复杂。看看下面的例子 $sql = "BEGIN;INSERT INTO TABLE_A (a, b, c) VALUES('42', '12', '\'ab\'c; DE
$array = explode( ";", $sql );
因为这一行是在一个从整个系统调用的子程序中,所以我想用一个可以正确分割事物的东西来替换这一行,而不会破坏系统的其余部分。我以为我会用str_getcsv成为赢家,但这也不够复杂。看看下面的例子
$sql = "BEGIN;INSERT INTO TABLE_A (a, b, c) VALUES('42', '12', '\'ab\'c; DEF');INSERT INTO TABLE_B (d, e, f) VALUES('42', '43', 'XY\'s Z ;uvw') ON DUPLICATE KEY UPDATE f='XY\'s Z ;uvw';COMMIT;";
$array = str_getcsv($sql, ";", "'");
foreach( $array as $value ) {
echo $value . "<br><br>";
}
$sql=“BEGIN;在表A(A,b,c)中插入值('42','12','ab'c;DEF');在重复键更新时插入表b(d,e,f)中的值('42','43','XY's Z;uvw');提交;”;
$array=str_getcsv($sql,“;”,“”);
foreach($array作为$value){
回显$value。“
”;
}
当我运行时,输出如下:
开始
在表A(A,b,c)中插入值('42','12','\'ab'c
定义')
在表_B(d,e,f)中插入值('42','43','XY's Z
重复关键点更新f='XY's Z时的uvw')
uvw'
承诺
所以它没有注意到分号在引号中。(据我所知,系统中不同位置的带引号的字符串总是单引号,但有时它们可能是双引号,对此我不确定。)
谁能告诉我怎么做?我想我可以用一个非常复杂的正则表达式来实现这一点,但这是我无法理解的。(*SKIP)(*FAIL)Magic
这将显示下面两个选项的输出(带或不带分号)
这就是您需要的:
$splits = preg_split('~\([^)]*\)(*SKIP)(*F)|;~', $sql);
看到我们在右边分号上分开
输出:
[0] => BEGIN
[1] => INSERT INTO TABLE_A (a, b, c) VALUES('42', '12', '\'ab\'c; DEF')
[2] => INSERT INTO TABLE_B (d, e, f) VALUES('42', '43', 'XY\'s Z ;uvw')
[3] => COMMIT
[4] =>
[0] => BEGIN;
[1] => INSERT INTO TABLE_A (a, b, c) VALUES('42', '12', '\'ab\'c; DEF');
[2] => INSERT INTO TABLE_B (d, e, f) VALUES('42', '43', 'XY\'s Z ;uvw');
[3] => COMMIT;
空项#4是最终另一侧的匹配项代码>。另一种选择是保留分号(见下文)
选项2:保留分号
如果要保留分号,请执行以下操作:
$splits = preg_split('~\([^)]*\)(*SKIP)(*F)|(?<=;)(?![ ]*$)~', $sql);
解释
这个问题是本问题中解释的技术的一个经典案例
在交替的左侧,regex\([^)]*\)
匹配complete(括号)
,然后故意失败,之后引擎跳转到字符串中的下一个位置。右侧与匹配代码>您想要的单词,我们知道它们是正确的,因为它们与左边的表达式不匹配。现在可以在上面拆分了
在选项2中,我们保留分号,右边的匹配匹配位置,但不匹配字符。这个位置是由lookback(?嘿,这里,跟进一下。其中一个答案是否为您解决了问题,或者问题是否仍然存在?请给我们一些反馈。:)这正是我要寻找的。这是一种享受。谢谢。我们需要在不久的将来观看您的实时php演示。刚刚遇到另一种情况,这种情况不起作用,即SQL语句确实有一个“ON replicate”部分,在这种情况下,参数不在括号中。我已经更新了问题以反映这一点。好的,我已经解决了,你提供的链接证明非常有用。如果我将正则表达式更改为“~([^)]*)(*跳过)(*F)\\”(?:\\\'\\'\\\\\'.[^\'])*”(*跳过)(*F)\~”它起作用了。也许你可以在你的答案中更新它,让其他人看到这个答案。如果其他人不熟悉(*SKIP)(*FAIL)
黑魔法,你可以在中阅读。@EdCottrell谢谢你,Ed!更直接的是,请参见perl文档中的。添加到参考资料中,好主意,谢谢。:)