LoginSignup
4
4

More than 3 years have passed since last update.

[PHP] 正規表現で SQL のキーワードだけを一発で大文字/小文字変換する

Last updated at Posted at 2019-11-20

背景

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\"";
4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4