文章やデータの中から、! や #、( のような半角の記号だけを探したい、まとめて取り除きたい、ということがあります。記号を 1 つずつ検索するのは大変ですが、正規表現 (文字の並びのパターンを表す書き方) の文字クラスを使えば、1 回の検索で済みます。
半角の記号をまとめて表す文字クラス
半角の記号は、次の文字クラスで表せます。
[!-/:-@\[-`{-~]
[ ] は「この中のどれか 1 文字」を表す文字クラスです。a-z のように - でつなぐと、文字コードの範囲を指定できます。半角の英数字と記号は、ASCII という文字コードの表の順に並んでいて、記号は、数字や英字のあいだの 4 か所に分かれて置かれています。
範囲 文字コード 含まれる記号
!-/ 0x21〜0x2F ! " # $ % & ' ( ) * + , - . /
:-@ 0x3A〜0x40 : ; < = > ? @
\[-` 0x5B〜0x60 [ \ ] ^ _ `
{-~ 0x7B〜0x7E { | } ~
0x30〜0x39 が数字、0x41〜0x5A が英字の大文字、0x61〜0x7A が小文字なので、そのすき間を 4 つの範囲で拾っている、というわけです。合わせて 32 文字になります。
- 3 つめの範囲の始まりの
[は、文字クラスの中で特別な意味を持つことがあるので、\[と書いておきます \(0x5C) と](0x5D) は、この範囲に含まれるので、別に書く必要はありません- 空白 (0x20) は含まれません。空白も対象にしたいときは、最初の範囲を
[ -/のように空白から始めます
日本語のフォントでは、\ が円記号 (¥) の形で表示されることがありますが、同じ文字です。
道具によっては、同じ記号を [[:punct:]] (POSIX の文字クラス) と書けるものもあります。ただし、JavaScript の正規表現では使えず、どの文字が含まれるかも道具や設定によって違うことがあります。
全角の記号は含まれない
この文字クラスに一致するのは ASCII の記号だけで、「!」「(」のような全角の記号は含まれません。全角の英数字と記号 (U+FF01〜U+FF5E) は、ASCII の記号と同じ順に並んでいるので、同じ形の範囲で表せます。
[!-/:-@[-`{-~]
句読点の「、」「。」やかぎかっこ「」は、別の場所 (U+3000 から始まる区画) にあるので、これにも含まれません。また、波ダッシュ「〜」(U+301C) は、全角のチルダ「~」(U+FF5E) とは別の文字です。入力する環境によってどちらになるかが違うので、検索で見つからないときは疑ってみてください。
Unicode の文字の種類で指定する
Unicode に対応した正規表現では、文字の種類 (一般カテゴリー) で指定する \p{...} が使えることがあります。
\p{P} 句読点: ! " # % & ' ( ) * , - . / : ; ? @ [ \ ] _ { } や 、 。 「 」 ・ ※ など
\p{S} 記号: $ + < = > ^ ` | ~ や ¥ 〒 など
半角の記号は、Unicode では句読点 (P) と記号 (S) の 2 つに分かれています。そのため、半角の記号を全部探すには、[\p{P}\p{S}] のように両方を指定します。ただし、こちらは全角の記号や、ほかの言語の記号も含みます。半角だけに絞りたいときは、先の文字クラスを使います。
JavaScript では、u フラグを付けたときに \p{...} が使えます。
const text = "価格は$100です。(税込)";
// 句読点と記号をまとめて取り除く (全角の記号も含む)
console.log(text.replace(/[\p{P}\p{S}]/gu, "")); // 価格は100です税込
置換の例
取り除くだけなら、検索に [!-/:-@\[-`{-~]、置換に空の文字列を指定して、すべて置換します。
全角に直したいときは、エディターの置換では難しいことがあります。多くのエディターの置換では、一致した文字の文字コードを計算して、別の文字にすることができないからです。全角の英数字・記号は、対応する半角の文字コードに 0xFEE0 を足した位置にあるので、スクリプトで処理します。
// 半角の記号を、対応する全角の記号に変える
function toFullwidthSymbols(text) {
return text.replace(/[!-\/:-@\[-`{-~]/g, (c) =>
String.fromCharCode(c.charCodeAt(0) + 0xfee0)
);
}
console.log(toFullwidthSymbols("(注意!)")); // (注意!)
JavaScript の正規表現リテラルの中では、/ を \/ と書いています。
反対に、全角を半角に直すなら、"!".normalize("NFKC") のように Unicode の正規化 (NFKC) を使う方法もあります。ただし、NFKC は「①」を「1」に、半角のカタカナを全角に変えるなど、記号以外の文字も変えるので、結果を確かめてから使ってください。
道具ごとの違いに気をつける
正規表現は、道具によって書き方 (方言) が少しずつ違います。\p{...} が使えるか、文字クラスの中の [ に \ が要るか、置換の文字列で一致した部分を $1 と書くか \1 と書くか、などが変わります。同じエディターでも、開いているファイルの中の検索と、フォルダー全体の検索で、別の仕組みを使っていることがあります。
置換する前に、まず検索だけを行って、一致した箇所の数と場所を確かめましょう。大事なファイルは、置換の前にコピーを取っておくか、Git などで元に戻せる状態にしておくと安心です。
まとめ
- 半角の記号は
[!-/:-@\[-`{-~]でまとめて検索できる (ASCII の 32 文字) - 全角の記号は含まれない。全角の英数字・記号は
[!-/:-@[-`{-~]で表せる \p{P}(句読点) と\p{S}(記号) は、全角やほかの言語の記号も含む- 道具ごとに正規表現の方言が違うので、検索で確かめてから置換する