正規表現でテキスト処理 -ひとりアドベントカレンダー Flutter編 2018 その4-
最近は専用のAPI経由でフォーマット済みのデータを取得して使用することが多くなりましたが、それでもまだまだベタなテキストを処理する機会は存在します。そんなテキスト処理のときに力を発揮するのが正規表現。もちろんDartでも使えます。
ということで、4日目は正規表現を使ってみたいと思います。
昨日までの内容と今後については目次を参照してください。
マテリアルアイコンを一覧表示させるためには、一覧表示させるための元リストが必要になります。例えばIconsにforeachなどのメソッドがあればいいのですが、個別にIconDataを取得する方法しか準備されてなさそうです。
そんな場合はどうしたら良いでしょう?
Flutterはオープンソースで開発されてますので、ソースを確認してみればどのゲッターにどのアイコンが割り当てられてるかわかりそうです。
実際にGitHubにあるFlutterのリポジトリを探してみると、良いソースページを見つけることができます。
ただ、このページは実際のソースなのでこのまま評価・実行してもFlutterと同じ実装になるだけです。
なので、今回は正規表現を使ってパースしてみたいと思います。
Flutterでは上記ページのように任意のフォントファミリーとコードポイントからIconDataを作成することができますので、今回は
1. Flutterに定義されてるIconData名のリスト
2. 個々のIconDataに割り当てられているコードポイント
3. 使われているフォントファミリー
を抜き出せば良さそうです。
が、フォントファミリーはすべて同じようなので実質3は不要です(3,000行近くありますので、全部は確認してません)。
早速定義されてる内容を見てみましょう。抜き出すとこんな感じになっています。
/// <i class="material-icons md-36">360</i> — material icon named "360".
static const IconData threesixty = IconData(0xe577, fontFamily: 'MaterialIcons');
この場合、IconData名は「threesixty」でコードポイントは「0xe577」となります。
正規表現自体は他言語とそれほど違いはありません。今回の場合はこんな感じになるでしょうか?
RegExp regexp = RegExp(r'iconData\s(.*?).*IconData\((.*?),');
正規表現自体は素直に書けますので、あまり難しいところはありません。たまにありますよね、エスケープにエスケープを重ねて何書いてあるのかわからなくなる言語。
そしてマッチした部分を使うときは以下のようにします。
regexp.allMatches(res.body).forEach((match) {
String iconName = match.group(1);
String codePoint = match.group(2);
});
あまり詳しくないのですが、Pythonって感じでしょうか?
だとするとJSの置き換えを狙いながらもPythonっぽいところを持ってくるあたり、さすがGoogleが開発してる言語という感じです。
正規表現の指定はよくある感じで、利用方法はちょっとPythonっぽい?ってところで今回は終わりにしておきます。
次回はプログラムから先に紹介したデータを取得し、今回作成した正規表現で処理してみたいと思います。
・・・
Twitterにもちょくちょく顔を出しています。フォローしていただけると内容にも気合が入ります。