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