在 php 中用分号分割 sql 语句(但不在引号内)

2024-02-29

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

$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

插入 TABLE_A (a, b, c) VALUES('42', '12', '\'ab\'c

DEF')

插入 TABLE_B (d, e, f) VALUES('42', '43', 'XY\'s Z

uvw') 重复密钥更新 f='XY\'s Z

uvw'

COMMIT

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

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


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

This 现场 PHP 演示 https://ideone.com/woTUa8显示以下两个选项的输出(带或不带分号)。

这就是您所需要的:

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

See demo http://regex101.com/r/bT5vD0看看我们是在右边的分号上分开的。

Output:

[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);

Output:

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

解释

这个问题是这个问题中解释的技术的一个经典案例“正则表达式-匹配模式,排除...” https://stackoverflow.com/q/23589174/

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

在选项 2 中,我们保留分号,右侧的匹配匹配一个位置,但不匹配字符。该位置由后视断言(?<=;),它断言;紧接在该位置之前,并且负向前看(?![ ]*$),它断言接下来的内容不是字符串末尾的可选空格(因此我们避免最后一个空匹配)。

示例代码

请检查现场 PHP 演示 https://ideone.com/woTUa8.

参考

  • 如何匹配(或替换)除 s1、s2、s3... 情况之外的模式 https://stackoverflow.com/q/23589174/
  • 关于匹配模式的文章,除非... http://www.rexegg.com/regex-best-trick.html
  • 前向和后向零长度断言 http://www.regular-expressions.info/lookaround.html
  • 掌握前瞻和后瞻 http://www.rexegg.com/regex-lookarounds.html
  • 特殊回溯控制动词 http://perldoc.perl.org/perlre.html#Special-Backtracking-Control-Verbs
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 php 中用分号分割 sql 语句(但不在引号内) 的相关文章

  • 提交表单后重定向是一个好习惯吗?

    我最近开始在提交网站上的某些表单 主要与购物车应用程序相关 后进行 header 重定向 到同一页面 以便用户不会通过刷新页面来执行意想不到的操作或者 后退 或 前进 并刷新页面 这是可以接受的做法吗 这是标准做法 称为redirect a
  • JavaScript 用空格分割字符串

    我想分割一个字符串 但我想保留空白 例如 var str my car is red var stringArray stringArray 0 my stringArray 1 stringArray 2 car stringArray
  • 多语言网站的 .htaccess 规则

    我正在重新设计 PHP 多语言网站 en es de fr ru 的 URL 该网站的 URL 是这样的 www mysite com page www mysite com page subpage1 www mysite com pag
  • Ruby Regex 舍入尾随零

    我正在寻找一个正则表达式来删除十进制数字中的尾随零 它应该返回以下结果 0 0002300 gt 0 00023 10 002300 gt 10 0023 100 0 gt 100 1000 gt 1000 0 0 gt 0 0 gt 0
  • Laravel 5.4 密码重置

    我有一个 Laravel 5 4 应用程序 我的管理区域中有一个视图 允许我查看所有用户 我想创建一个功能 允许我单击后端的按钮 自动发送默认 Laravel 密码重置功能的过程 在我看来 我有以下几点 table class table
  • 选择早于的时间戳

    我如何从数据库中选择超过 12 小时的项目 我使用时间戳列来存储时间 但我认为我不需要年 月 日 只需要小时 我有类似的东西 但它不起作用 没有错误 只是从表中返回所有数据 sql SELECT FROM Y WHERE X and tim
  • 比较 PHP 中的 unix 时间戳 [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 在 PHP 中我有 diff abs
  • 将 Javascript 正则表达式转换为 PHP

    我知道这个问题已经被问了大约十几次 但是从技术上讲 这个问题并不是一个骗局 如果您愿意 请检查其他问题 基本上 我有一个 Javascript 正则表达式来检查用于前端验证的电子邮件地址 并且我使用 CodeIgniter 在后端进行双重检
  • 为什么 opcache 没有刷新?

    我用guzzlehttp guzzle封装在拉拉维尔 8 升级到后PHP 8 I get Symfony Component ErrorHandler Error FatalError Invalid opcode 117 2 0 in f
  • 将 __DIR__ 常量与字符串连接作为数组值,该数组值是 PHP 中的类成员

    谁能告诉我为什么这不起作用 这只是我在其他地方尝试做的事情的一个粗略的例子 stuff array key gt DIR value 但是 这会产生错误 PHP Parse error syntax error unexpected exp
  • 如何向 opencart 管理添加新模块?

    我想在 opencart 管理中将子菜单项 位置 添加到 目录 菜单项 在选择位置时 我想看到我自己的位置管理视图页面 该页面与 opencart 数据库中我自己的位置表相互关联 请让我知道在哪里以及创建什么 mvc 才能在开放购物车中实现
  • 为什么 symfony DOMCrawler 对象无法在依赖的 phpunit 测试之间正确传递?

    我有一个适用于我的 symfony 应用程序的 phpunit 测试套件 在该测试文件中 我在不同的测试之间有一些依赖关系 并在依赖关系之间传递一个 DOMCrawler 对象 这样我就不必每次都导航到它 但是 在采用我所做的方法时 您似乎
  • 优化正则表达式来解析中文拼音[关闭]

    这个问题不太可能对任何未来的访客有帮助 它只与一个较小的地理区域 一个特定的时间点或一个非常狭窄的情况相关 通常不适用于全世界的互联网受众 为了帮助使这个问题更广泛地适用 访问帮助中心 help reopen questions 我有一个有
  • 根据 WooCommerce 中的特定付款方式添加费用

    在 WooCommerce 中 我需要为特定支付网关申请自定义手续费 我这里有这段代码 如何向 WooCommerce Checkout 添加手续费 http www endocreative com add handling fee wo
  • 正则表达式没有按预期工作?

    我有这个正则表达式 new RegExp a z 0 9 ig 我正在测试一个不应该工作的字符串 vc 但它确实通过了测试 而且它不应该 new RegExp a z 0 9 ig test vc true 但如果我删除其中一个 or or
  • 将文本中的所有 URL 替换为 PHP 中的可点击链接[重复]

    这个问题在这里已经有答案了 我有一个用 PHP 编写的 Web 应用程序 我想找到用户评论中的所有 URL 并将它们更改为可点击的链接 我搜索了很多网站和页面 找到了以下解决方案 不幸的是我没有再次找到它的参考链接 感谢其作者 该代码可以完
  • 修复 PHP 中格式错误的 HTML?

    我正在根据用户提供的片段构建一个大型 HTML 文档 这些用户有以各种方式格式错误的烦人习惯 浏览器足够强大且宽容 但我希望能够验证并 理想情况下 修复任何格式错误的 HTML 如果可能的话 例如 td b Title b td 可以合理地
  • 自定义 php 论坛 - 显示新的/未读的帖子

    我自己使用 php 编写了一个自定义论坛脚本 我决定不使用 phpbb 和其他工具 因为我希望我所做的事情具有 100 的灵活性 不过我遇到了一个问题 如何向用户显示帖子是否是新的 未读的 我想到了两种解决方案 1 饼干 2 数据库 我不想
  • 用于验证 InetSocketAddresses 的正则表达式(ipv4/v6 + 端口地址)

    我在寻找testedipv4 和 ipv6 的正则表达式InetSocket地址 http download oracle com javase 6 docs api java net InetSocketAddress html toSt
  • 在 python 中使用 re.sub 将字母变成大写?

    在许多编程语言中 以下内容 find foo a z bar并替换为GOO U 1GAR 将导致整个匹配项变为大写 我似乎无法在 python 中找到等效项 它存在吗 您可以将函数传递给re sub http docs python org

随机推荐