gpt4 book ai didi

php - 在分号上拆分 php 中的 sql 语句(但不在引号内)

转载 作者:可可西里 更新时间:2023-10-31 22:43:16 25 4
gpt4 key购买 nike

当用户在自由格式字段中使用分号时,我的系统会导致错误。我将其追溯到一个简单的爆炸语句:

$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>";
}

当我运行它时输出如下:

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

所以它没有注意到分号在引号内。 (据我所知,系统中不同地方的引用字符串总是用单引号引起来,但有时它们可​​能是双引号,我不确定。)

谁能告诉我怎么做?我怀疑我可以使用非常复杂的正则表达式来做到这一点,但这超出了我的理解范围。

最佳答案

(*跳过)(*失败)魔法

live PHP demo向您显示以下两个选项的输出(带或不带分号)。

这是你需要的:

$splits = preg_split('~\([^)]*\)(*SKIP)(*F)|;~', $sql);

See demo看到我们在正确的分号处 split 。

输出:

[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] =>

空项目 #4 是决赛另一边的比赛 ; .另一种选择是保留分号(见下文)。

选项 2:保留分号

如果你想保留分号,用这个:

$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;

解释

这个问题是这个问题中解释的技术的经典案例 "regex-match a pattern, excluding..."

在交替的左侧| , 正则表达式 \([^)]*\)匹配完成(parentheses)然后故意失败,之后引擎跳到字符串中的下一个位置。右侧匹配 ;你想要的词,我们知道它们是正确的,因为它们与左边的表达式不匹配。现在可以安全拆分了。

在选项 2 中,我们保留分号,右边的匹配项匹配一个位置,但不匹配任何字符。该位置由 lookbehind (?<=;) 断言,它断言 ;紧接在位置之前,负前瞻 (?![ ]*$) , 它断言后面的不是可选空格然后是字符串的结尾(因此我们避免了最后一个空匹配)。

示例代码

请检查 live PHP demo .

引用

关于php - 在分号上拆分 php 中的 sql 语句(但不在引号内),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24423260/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com