【问题标题】:Auto Append string to Matched phrases php自动将字符串附加到匹配的短语 php
【发布时间】:2020-11-21 11:39:52
【问题描述】:

这里有点问题,已经搜索但找不到类似的东西。

使用像 preg_match_all 这样的函数没有问题,但我希望能够在不完全替换它的情况下为所有匹配项预先添加一个字符串。

我想自动为查询中的所有表名添加表前缀。

得到这个代码

if(preg_match_all('/((FROM|JOIN) `(.*)`)/', $str, $matches)) {
    $tables = $matches[3];
}

这似乎至少适用于 SELECT & JOIN 查询,但还不知道其他查询。 但我希望能够为匹配的表名自动添加特定的前缀;不只是列出来,

任何想法;这是否可行。

只是想避免在查询期间必须在表名前添加表前缀。

输入示例:

SELECT mail_id, mail_date, mail_from, mail_to, mail_subject, (
            (
            SELECT COUNT(*)
            FROM messagecenter_qmails
            WHERE qmail_mail_id = mail_id
            ) + (
            SELECT COUNT(*)
            FROM `messagecenter_rels`
            WHERE rel_mail_id = mail_id
            )
            ) AS email_total, (
            SELECT COUNT(*)
            FROM `messagecenter_rels`
            WHERE rel_mail_id = mail_id
            ) AS email_sent, (
            SELECT COUNT(*)
            FROM `messagecenter_rels`
            INNER JOIN email_receives ON receive_reply_to = rel_sent_id
            WHERE rel_mail_id = mail_id
            ) AS email_reply FROM messagecenter_emails WHERE mail_draft='No' ORDER BY mail_id ASC LIMIT 0,10

预期输出:

SELECT mail_id, mail_date, mail_from, mail_to, mail_subject, (
            (
            SELECT COUNT(*)
            FROM sys_messagecenter_qmails
            WHERE qmail_mail_id = mail_id
            ) + (
            SELECT COUNT(*)
            FROM `sys_messagecenter_rels`
            WHERE rel_mail_id = mail_id
            )
            ) AS email_total, (
            SELECT COUNT(*)
            FROM `sys_messagecenter_rels`
            WHERE rel_mail_id = mail_id
            ) AS email_sent, (
            SELECT COUNT(*)
            FROM `sys_messagecenter_rels`
            INNER JOIN sys_email_receives ON receive_reply_to = rel_sent_id
            WHERE rel_mail_id = mail_id
            ) AS email_reply FROM sys_messagecenter_emails WHERE mail_draft='No' ORDER BY mail_id ASC LIMIT 0,10

您可以看到两个代码/查询之间的唯一区别是输入表名称没有前缀,例如 email_receives,而结果有表前缀,例如 sys_email_receives

【问题讨论】:

  • 你能举一个输入和预期输出的例子吗?
  • 按要求添加了输入和预期输出示例。希望下次不需要提醒我
  • 听起来你需要preg_replace。这是short read
  • 不确定 preg_replace 是否会进行字符串替换,因此如果初始匹配是 Cats 并且我想在其前面加上 My_,它将变为 My_ 而不是 My_Cats 。希望实现的是 Match 和 prePend ,因此它匹配表名 Cats 并在其前面加上前缀,因此我们有 My_Cats
  • 有什么好的理由这样做,而不是正确解析字符串?如果表列(或查询中的其他任何内容)包含子字符串 FROMJOIN 怎么办?

标签: php preg-match-all


【解决方案1】:

一种选择是使用preg_replace 和 3 个捕获组。

\b(?:FROM|JOIN)\h+\K(`)?([^\s`]+)((?(1)`))(?!\S)

说明

  • \b(?:FROM|JOIN)\h+\K 匹配 FROM 或 JOIN 后跟 1+ 个水平空白字符。然后使用\K 重置匹配缓冲区
  • (`)? 可选捕获组1,匹配反引号
  • ([^\s`]+) 捕获组 2,匹配 1+ 个字符,而不是反引号或空白字符
  • ((?(1)))` 捕获第 3 组,如果第 1 组存在,则 if 子句匹配反引号
  • (?!\S) 负前瞻,在右侧断言空白边界

Regex demo | Php demo

在替换中使用带有sys_的3个捕获组

$1sys_$2$3

例如

$result = preg_replace('/\b(?:FROM|JOIN)\h+\K(`)?([^\s`]+)((?(1)`))(?!\S)/', '$1sys_$2$3', $str);

【讨论】:

    【解决方案2】:

    preg_replace 是正确的函数。使用反向引用可以在更换过程中重复使用已识别的部件。

    $newSql = preg_replace('~(FROM|JOIN) +`([^`]+)`~','$1 `sys_$2`',$sql);
    

    $1 : 在第一个括号中识别的字符串,这里是 FROM 或 JOIN

    $2 : 表名

    我设置的前缀修复。

    【讨论】:

    • 据我所知,@The Fourth Bird 的解决方案就是这样做的。
    猜你喜欢
    • 2021-10-03
    • 2023-03-11
    • 1970-01-01
    • 2022-01-21
    • 2022-01-03
    • 2011-09-02
    • 2016-07-14
    • 2020-03-09
    • 1970-01-01
    相关资源
    最近更新 更多