背景
mysqldump
とかで吐き出したやつの大文字小文字を統一したいけど,いい感じのフォーマッタが見つからなかったので正規表現で雑に捌いてみた。制約として,カラム名やテーブル名などはすべてクオート記号で括られている必要があります。
実装
関数定義
function lowerCaseKeywords(string $sql): string
{
static $regex = <<<'EOD'
/
((`)|(")|(')) (?# クオーテーション開始)
(?:
(?:\1\1)++ (?# 連続で並べるクオーテーションのエスケープ)
|
(?:\\\1)++ (?# バックスラッシュを頭につけるクオーテーションのエスケープ)
|
(?:\\\\)++ (?# 連続で並べるバックスラッシュのエスケープ)
|
(?(2)[^`]++|(?(3)[^"]++|[^']++)) (?# 該当しないクオーテーションの連続)
)*+
\1 (?# クオーテーション終了)
|
([^`"']++) (?# 置換したい文字列)
/x
EOD;
return preg_replace_callback($regex, function ($matches) {
return empty($matches[5]) ? $matches[0] : strtolower($matches[0]);
}, $sql);
}
使用例
$sql = <<<'EOD'
CREATE TABLE `Articles`(
`ID` Bigint(20) Unsigned NOT NULL AUTO_INCREMENT,
`Title` Varchar(191) NOT NULL default "No Title",
`Body` Text NOT NULL,
PRIMARY KEY (`ID`)
) DEFAULT CHARSET=utf8mb4 COMMENT='This is a table for ''Article''';
CREATE TABLE `Comments`(
`ID` Bigint(20) Unsigned NOT NULL AUTO_INCREMENT,
`Article_ID` Bigint(20) Unsigned NOT NULL,
`Body` Text NOT NULL,
FOREIGN KEY `FK_Article_ID`(`Article_ID`) REFERENCES `Articles`(`ID`)
) DEFAULT CHARSET=utf8mb4 COMMENT="This is a table for \"Comment\"";
EOD;
echo lowerCaseKeywords($sql);
実行結果
create table `Articles`(
`ID` bigint(20) unsigned not null auto_increment,
`Title` varchar(191) not null default "No Title",
`Body` text not null,
primary key (`ID`)
) default charset=utf8mb4 comment='This is a table for ''Article''';
create table `Comments`(
`ID` bigint(20) unsigned not null auto_increment,
`Article_ID` bigint(20) unsigned not null,
`Body` text not null,
foreign key `FK_Article_ID`(`Article_ID`) references `Articles`(`ID`)
) default charset=utf8mb4 comment="This is a table for \"Comment\"";