我搜索方法以获得较低的字符串,但不会更改引号内的文本大小写。
字符串:
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
答案 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语法不同,反斜杠必须转义两次。