PHP Regexp strtolower函数,用于维护引号中文本的大小写


PHP Regexp strtolower function that maintains case of text within quotes

我搜索一个方法以获得较低的字符串,但不更改引号中文本的大小写。

字符串:

SELECT * FROM UtilisateurApplicatif WHERE idUtilisateurApplicatif <> "-1" AND Identification = "TOTO" AND MotDePasse = "TotoTUTU" AND Actif = 1

我想要的结果:

select * from utilisateurapplicatif where idutilisateurapplicatif <> "-1" and identification = "TOTO" and motdepasse = "TotoTUTU" and actif = 1

您可以使用preg_replace_callback来执行此操作,该操作允许对匹配结果应用函数:

$subject = <<<'LOD'
SELECT * FROM UtilisateurApplicatif
WHERE idUtilisateurApplicatif <> "-1"
AND Identification = "TOTO"
AND MotDePasse = "Toto'"TUTU" AND Actif = 1
LOD;
$pattern = <<<'LOD'
~
(?(DEFINE) 
    (?<DQuotedContent>
        (?> [^"'']++ | (?:''{2})++ | ''. )*
    )
)
" 'g<DQuotedContent> " 'K | [A-Z]++
~x
LOD;
$result = preg_replace_callback($pattern,
    function ($match) { return strtolower($match[0]); },
    $subject);
print_r($result);

图案说明:

该模式的思想是匹配之前引用的部分,并将它们从匹配结果中删除,以不应用strtolower

首先,我定义了一个子模式(DQuotedContent),其中所有可能的内容都在双引号之间,即:

  • 所有不是双引号或反斜杠的字符[^"'']
  • 所有偶数反斜杠(?:''{2})++(不能转义任何内容)
  • 转义字符(转义的双引号不能关闭带引号的字符串)

模式的主要部分现在很容易编写:

" 'g<DQuotedContent> "      # quoted part
'K                          # reset all that have been matched before
|                           # OR
[A-Z]++                     # uppercase letters

注意,'K非常有用,因为它从匹配中删除了引用的部分。因此,回调函数不必知道匹配了什么就可以应用strtolower

注意:为了提高可读性,我已经使用nowdoc语法、define部分、命名子模式和注释模式(~x)编写了该模式,但您可以在更紧凑的版本中使用相同的模式:

$pattern = '~"(?>[^"''']++|(?:'''{2})++|'''.)*"'K|[A-Z]++~';

与nowdoc语法不同,反斜杠必须转义两次