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

时间:2013-07-31 23:59:45

标签: php regex

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

字符串:

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

1 个答案:

答案 0 :(得分: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语法,定义部分,命名子模式和注释模式(~x)编写了模式以提高可读性,但您可以在更紧凑的情况下使用相同的模式版本:

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

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