代码之家  ›  专栏  ›  技术社区  ›  Martin Bean

我的preg匹配语法有效吗?

  •  2
  • Martin Bean  · 技术社区  · 14 年前

    我正在添加一个 if 语句到我的数据库抽象层,以选择对少数数据库表的任何尝试查询。

    基本上,如果我的应用程序试图从一个名为 members members_profiles 我想调用我的 如果 语句。

    if (
        preg_match('/INSERT INTO [members|members_profiles]/', $sql) ||
        preg_match('/UPDATE [members|members_profiles]/', $sql) ||
        preg_match('/DELETE FROM [members|members_profiles]/', $sql))
    {
        // do if statement stuff here...
    }
    

    我不是正则表达式/preg-match-master,但是上面会吗? 如果 如果SQL查询匹配,则语句返回true:

    • INSERT INTO members ... INSERT INTO members_profiles ...
    • UPDATE members ... UPDATE members_profiles ...
    • DELETE FROM members ... DELETE FROM members_profiles ...

    或者我的preg-match语法还差吗?

    5 回复  |  直到 14 年前
        1
  •  2
  •   jigfox    14 年前

    只要一个regex就足够了:

    if (preg_match('/(?i)(INSERT\s+INTO|UPDATE|DELETE\s+FROM)(?-i)\s+(members|members_profiles)/', $sql))
    {
        // do if statement stuff here...
    }
    

    注意 () 而不是 [] \s+ 而不是空格。因为SQL对任何数量的nay空格都有效,并且 s+ 全部匹配。这个 + 后面 \s 意味着它必须至少有一个空白,但可以有更多的空白。这个 (?i) 意味着所有以下字符都将被检查为不区分大小写,并且 (?-i) 再次打开区分大小写。因为SQL命令不区分大小写。

    (abc|def) 比赛 abc def
    [abc|def] 比赛 a , b , c , | , d , e f

    要尝试使用正则表达式,可以使用 http://rubular.com/ 它说它是用Ruby编写的,用于在Ruby中测试regex,但是有效的regex应该独立于语言,所以它可以用来测试在其他语言中也可以工作的公共正则表达式。

        2
  •  6
  •   kennytm    14 年前

    语法有效,但不会执行您想要的操作。

    对于图案的交替,使用

    preg_match('/INSERT INTO (?:members|members_profiles)/', $sql) ||
    //                       ^^^                        ^
    

    在PCRE, […] 定义字符类。这将匹配1个字符,因为它出现在括号内。以你为例 [members|members_profiles] 将匹配1个字符,如果它是 b , e , f , i , l , m , o , p , r , s , | _ .

    分组是使用另一种括号完成的, (?:…) .


    (顺便说一句,请 不要 使用regex检测数据库更改尝试。限制数据库用户的权限。)

        3
  •  2
  •   Bart Kiers    14 年前

    正则表达式

    [ab|cd]
    

    也不匹配 ab cd 但符合以下条件之一 单一的 (!)字符: a , b , | , c d .

    您需要的是组而不是字符类:

    (ab|cd)
    

    哪一个匹配 抗体 光盘 .

    有关角色类的详细信息: http://www.regular-expressions.info/charclass.html

        4
  •  0
  •   Bogdan Constantinescu    14 年前

    这是正确的

    if (
        preg_match('/INSERT\sINTO\s(members|members_profiles)/', $sql) ||
        preg_match('/UPDATE\s(members|members_profiles)/', $sql) ||
        preg_match('/DELETE\sFROM\s(members|members_profiles)/', $sql))
    {
        // do if statement stuff here...
    }
    

    LE : 用空格特殊字符更改了空格转义

        5
  •  0
  •   avpaderno    14 年前

    除了其他用户已经报告的错误之外,如果需要检测查询何时试图更改表,则正则表达式的限制性太强。 members members_profiles .

    我不会使用这种方法,但是如果你真的需要这样做,那么考虑一下

    • 数据库引擎允许注释。如果数据库引擎是mysql,我可以写 INSERT INTO /* little trick */ members … INSERT /* into */ INTO /* table */ members … .
    • 数据库引擎允许任何数量的空格或新行字符。