正規表現におけるドット(.)の使い方や注意点を解説する
今回は、正規表現でも使う頻度の高いドット(.)の使い方や使う上での注意点を解説していきます。
正規表現のドット(.)の使い方
正規表現のドットは、「任意の文字と一致する」と言うメタ文字で、ザックリ言うと、「どんな文字でも一致する」メタ文字と言えます。
例えば、以下の様な文字であれば、正規表現のドットはマッチします。
- ローマ字、数字
- 漢字やひらがな等の日本語
- スペース、タブ
- その他の文字と言う文字
ただ、1つ注意なのが、ドット(.)でマッチしない文字として「\n」「\r\n」改行コードがあることです。なので、ファイルを読み込んでそのファイルの内容を正規表現で抜き出したい時に、ドットを使うと上手く処理ができないので注意が必要です。
参考: Regular Expressions - Why doesn't dot (.) match the newline character (" ")? | regex Tutorial
サンプルコードとして、以下のJavaScriptを挙げますが、言語は何でも良いです。
let regex = /./; // ここが正規表現
let str = "I"; // 調べる文字列
console.log(regex.exec(str));
// I と表示
正規表現のドット(.)の色々な使い方
以下、正規表現のドットにはどんな使い方ができるかを見ていきましょう。
ドットプラス(.+) - 1文字以上マッチしたい時
何か適当な文字を1文字以上マッチさせたい場合は、ドットプラス(.+)と書けばOKです。
let regex = /.+/;
let str = "I am taro {4649.-}";
console.log(regex.exec(str));
// I am taro {4649.-} と表示
ちなみにですが、let str = "I am taro {4649.-}";の中にあるドットは、正規表現のメタ文字としてのドットではなく、単に文字としてのドットです。
ドットアスタリスク(.*) - 0文字以上マッチしたい時
ドットアスタリスクは、「0文字以上とマッチ」つまり、「文字がない場合でもマッチするドットプラス」みたいな感じですね。
let regex = /.*/;
let str = "I am taro {4649.-}";
console.log(regex.exec(str));
// I am taro {4649.-} と表示
ドットをエスケープしたい、単に文字としてのドットを正規表現で使いたい
ドットをエスケープして単に文字としてのドットを正規表現にマッチさせたい場合は、「\.」とバックスラッシュの後にドットを書くと良いです。
例えば、先ほどのサンプルコードの正規表現を/.*/から/\.*/に変えると、全く異なる挙動をします。
let regex = /\.*/;
let str = "I am taro {4649.-}";
console.log(regex.exec(str));
// 文字列の途中の . だけマッチする
let regex = /\.*/;
let str = "...";
console.log(regex.exec(str));
// これは ... としてマッチする
ドットをエスケープする方法として[]を使う方法もあります。[]を使う事で、ドットとかの正規表現のメタ文字は、単なる文字として扱われるようになります。
let regex = /[.]*/;
let str = "I am taro {4649.-}";
console.log(regex.exec(str));
// これも文字列の途中の . だけマッチする
逆に[]の中でメタ文字としてのドットを使いたい場合は、今度は逆にバックスラッシュを書くことで、メタ文字のドットとして扱われるようになります。
let regex = /[\.]*/;
let str = "I am taro {4649.-}";
console.log(regex.exec(str));
// I am taro {4649.-} とマッチする
ドットはてな(.?) - 0or1文字とマッチする
ドットはてなは、0or1文字とマッチする時に使います。
似たようなものにドットアスタリスク (.*)がありましたが、.*の方は0文字以上、つまり5文字でも10文字でもマッチしますが、*?は0文字か1文字にしかマッチしません。
let regex = /.?/;
let str = "I am taro {4649.-}";
console.log(regex.exec(str));
// I とマッチする
実際に上のサンプルコードを見てわかるように、.*はI am taro {4649.-}とマッチしましたが、.?はIとしかマッチしていません。