正規表現によって大量の SwiftLint Warnings を解決する

先日、とあるプロジェクトに SwiftLint を導入したら、こんなことになりました。

大量の SwiftLint 警告

大量の SwiftLint 警告

本日はこの大量の SwiftLint 警告のうち、約 9 割を一瞬で解決した方法をご紹介します。

ただし、僕は正規表現をほとんど初めて書いたので、もっとスマートなやり方はありそうです。
そこだけご注意いただければと思います。 (もっといい正規表現思いついた方はコメントください 🙇🏻‍♂️)

Warnigns のほとんどを占めるルール

この 154 個 (実際には表示しきってないだけでもっとあった) のうちのほとんどが comment_spacing でした。

つまり、以下のように修正すれば解決したわけです。

//HogeHoge comment ← これを
// HogeHoge comment ← こう

追記: swiftlint autocorrect を使えば一発だよ

今回は「正規表現によって倒したよ」っていう話が本当はしたかったのですが、社内に共有したら、

swiftlint autocorrect 使いません?

とのこと。半信半疑で調べて swiftlint autocorrect を実行してみると、、、

全部、直ってる〜〜〜〜〜〜〜!!!!

しかも

// autocorrect 前
hoge { index in // 「index 使ってないなら _ とかにしといて」って注意されてる
    // index を使わない処理
}

// autocorrect 後
hoge { _ in
    // index を使わない処理
}

とかも直ってました。
皆さんも SwiftLint 導入したてで大量に Warning が出た場合は「取り敢えず swiftlint autocorrect を実行する!

これ、僕との約束です。

というわけで、この後は「autocorrect を使えば一発で解決するものをわざわざ工夫して正規表現で倒した話」をします。
興味がある方は流し見してください…

結論

結論を先に書いておくと、以下の画像のようにすればほとんど解決します。

解決した正規表現

解決した正規表現

テキストで書くと、 (\s//)([^\s/])$1 $2 って感じです。

ただ、これだと行頭にコメントが来ているものに対応できていないので、追加で、 (^//)([^\s/])$1 $2 の置換も実行すればほとんど解決すると思います。

まとめ

置換前のパターン置換後のパターン
(\s//)([^\s/])$1 $2
(^//)([^\s/])$1 $2

正規表現によるパターンマッチの解説

正規表現分かってる方は ↑ の正規表現だけ見て「ほーん、なるほど。そういうことね」ってなると思うんですけど、僕みたいに「正規表現使ったことない iOS エンジニア」の方もいらっしゃると思うので、この機に備忘録がてら解説します。

やりたいこととしては //hoge// hoge なので、日本語にすると「2 連続のバックスラッシュの後にスペース以外が来てる文字列」になります。

正規表現で「以外」は ^ で、スペースは \s によって表されるので、 //^\s で行けそうです。
ですが、これにはまだ罠があります。

  1. https://daichidaiji.com みたいな URL もマッチしてしまう
  2. /// の Doc. コメントにもマッチしてしまう

つまり、 https://daichidaiji.comhttps:// daichidaiji.com になり、 /// 関数の説明// / 関数の説明 になってしまい、問題ですよね。

URL にマッチさせないようにする

まずひとつ目ですが、コメントの前は大体スペースが来ているか、行頭にコメントを書くはずです。
なので、

  • 「2 連続のバックスラッシュ…」 → 「スペースの後に 2 連続のバックスラッシュ…」
    • //^\s\s//^\s
  • 「2 連続のバックスラッシュ…」 → 「行頭が 2 連続のバックスラッシュ…」になります。
    • //^\s^//^\s
      • 行頭は ^ で表されます。

とマッチさせれば URL にマッチすることはなくなりそうです。

/// のDoc. コメントにマッチさせないようにする

次に、 /// にもマッチしてしまう問題ですが、「2 連続のバックスラッシュの後にスペース以外が来てる文字列」 → 「2 連続のバックスラッシュの後にスペースまたは / 以外が来てる文字列」と変化させます。

これは [^] 構文を使います。
^ の後に省きたいパターンを書くことで「それ以外」をマッチさせます。

つまり、 //^\s//[^\s/] となります。

組み合わせる

  • スペースから始まるバージョン
    • \s//[^\s/]
  • 行頭から始まるバージョン
    • ^//[^\s/]

先程の正規表現を組み合わせて 2 つの正規表現ができました。

これを使えば目的の Warning が出ている箇所にマッチできるようになりました。

置換する

今度はこれを使って置換します。
// の後に半角スペースを入れたいですよね。

ここで、 // の後に続いている文字列は場所によって変わるので、共通した置換は使えません。
なので、マッチしたパターンを使いつつ置換することが求められますね。

これには ()${数字} を使います。

正規表現に対して () で囲むとグループ化することができます。
そして、そのまとまりの中身を ${数字} の数字で指定した順番のパターンを取り出せます。

今回の場合、「2 番目のスラッシュまで」と「スラッシュ後」の間にスペースを入れたいので、 \s//[^\s/] であれば、 (\s//)([^\s/]) としてまとまりを作り、置換後は $1 $2 と間にスペースを入れたものに置換すればいいのです!!

よって、無事最初に紹介した正規表現と置換ができた訳です。
ちょっとは今回の正規表現理解できたでしょうか?

余談: 可視化ツールのご紹介

正規表現について調べていると、いくつか可視化ツールが見つかりました。

以下の記事にまとめられていたので、紹介します。
正規表現チェックツールまとめ - Qiita

今回の正規表現を可視化ツールにかけてみるとこんな感じでした。
デバッグするのに便利そうですね。

正規表現1

正規表現1

正規表現2

正規表現2

おわり

2 つの正規表現を使ってしまっているのがスマートでは無いものの、、
今回の正規表現を使って、手動であれば何十分もかかっていたであろう作業を正規表現について調べた時間を含めて 5 分程度でできてしまいました。

正規表現を iOS 開発にもっと使えるようになったら、また紹介しようと思います。

Built with Hugo
テーマ StackJimmy によって設計されています。