角括弧 […] 内の複数の文字または文字クラスは、「指定された文字のいずれかを検索する」ことを意味します。
集合
たとえば、[eao] は、3 つの文字 'a'、'e'、または 'o' のいずれかを意味します。
これは集合と呼ばれます。集合は、通常の文字とともに正規表現で使用できます。
// find [t or m], and then "op"
alert( "Mop top".match(/[tm]op/gi) ); // "Mop", "top"
集合内に複数の文字がある場合でも、それらはマッチ内で正確に 1 つの文字に対応することに注意してください。
したがって、以下の例では一致するものはありません。
// find "V", then [o or i], then "la"
alert( "Voila".match(/V[oi]la/) ); // null, no matches
パターンは以下を検索します。
V,- 次に、文字
[oi]のいずれか、 - 次に、
la。
したがって、Vola または Vila の一致があります。
範囲
角括弧には、文字範囲を含めることもできます。
たとえば、[a-z] は a から z の範囲の文字であり、[0-5] は 0 から 5 の数字です。
以下の例では、"x" の後に 2 つの数字または A から F までの文字が続くものを検索しています。
alert( "Exception 0xAF".match(/x[0-9A-F][0-9A-F]/g) ); // xAF
ここで、[0-9A-F] には 2 つの範囲があります。これは、0 から 9 までの数字、または A から F までの文字のいずれかの文字を検索します。
小文字の文字も検索したい場合は、範囲 a-f を追加できます: [0-9A-Fa-f]。または、フラグ i を追加します。
[…] 内で文字クラスを使用することもできます。
たとえば、単語の文字 \w またはハイフン - を検索したい場合、集合は [\w-] です。
複数のクラスを組み合わせることもできます。たとえば、[\s\d] は「空白文字または数字」を意味します。
たとえば、
- \d – は
[0-9]と同じです。 - \w – は
[a-zA-Z0-9_]と同じです。 - \s – は
[\t\n\v\f\r ]と同じで、他にいくつかのまれな Unicode 空白文字も含まれます。
例: 多言語の \w
文字クラス \w は [a-zA-Z0-9_] の短縮形であるため、漢字、キリル文字などを見つけることはできません。
任意の言語の単語の文字を検索する、より普遍的なパターンを記述できます。これは Unicode プロパティを使用すると簡単です: [\p{Alpha}\p{M}\p{Nd}\p{Pc}\p{Join_C}]。
これを解読しましょう。\w と同様に、次の Unicode プロパティを持つ文字を含む独自の集合を作成します。
Alphabetic(Alpha) – 文字用。Mark(M) – アクセント記号用。Decimal_Number(Nd) – 数字用。Connector_Punctuation(Pc) – アンダースコア'_'および同様の文字用。Join_Control(Join_C) – アラビア語などの合字で使用される 2 つの特殊コード200cおよび200d。
使用例
let regexp = /[\p{Alpha}\p{M}\p{Nd}\p{Pc}\p{Join_C}]/gu;
let str = `Hi 你好 12`;
// finds all letters and digits:
alert( str.match(regexp) ); // H,i,你,好,1,2
もちろん、このパターンを編集して、Unicode プロパティを追加または削除できます。Unicode プロパティの詳細については、Unicode: flag "u" and class \p{...} の記事を参照してください。
Unicode プロパティ p{…} は IE では実装されていません。本当に必要な場合は、XRegExp ライブラリを使用できます。
または、興味のある言語の文字範囲 (たとえば、キリル文字の場合は [а-я]) を使用します。
範囲の除外
通常の範囲に加えて、[^…] のように見える「除外」範囲があります。
それらは先頭のキャレット文字 ^ で示され、指定された文字を除く任意の文字に一致します。
たとえば、
[^aeyo]–'a'、'e'、'y'、または'o'を除く任意の文字。[^0-9]– 数字を除く任意の文字。これは\Dと同じです。[^\s]– 空白以外の任意の文字。これは\Sと同じです。
以下の例では、文字、数字、スペースを除く任意の文字を検索します。
alert( "alice15@gmail.com".match(/[^\d\sA-Z]/gi) ); // @ and .
[…] でのエスケープ
通常、特殊文字を正確に検索したい場合は、\. のようにエスケープする必要があります。バックスラッシュが必要な場合は、\\ を使用します。
角括弧内では、エスケープせずにほとんどの特殊文字を使用できます。
- 記号
. + ( )はエスケープする必要はありません。 - ハイフン
-は、先頭または末尾 (範囲を定義しない場合) ではエスケープされません。 - キャレット
^は、先頭 (除外を意味する場合) でのみエスケープされます。 - 閉じ角括弧
]は、(その記号を検索する必要がある場合) 常にエスケープされます。
言い換えれば、すべての特殊文字は、角括弧に対して何らかの意味を持つ場合を除き、エスケープなしで許可されます。
角括弧内のドット . は、単なるドットを意味します。パターン [.,] は、ドットまたはコンマのいずれかの文字を検索します。
以下の例では、正規表現 [-().^+] は、文字 -().^+ のいずれかを検索します。
// No need to escape
let regexp = /[-().^+]/g;
alert( "1 + 2 - 3".match(regexp) ); // Matches +, -
…しかし、「念のため」エスケープすることに決めたとしても、害はありません。
// Escaped everything
let regexp = /[\-\(\)\.\^\+]/g;
alert( "1 + 2 - 3".match(regexp) ); // also works: +, -
範囲とフラグ "u"
集合にサロゲートペアがある場合は、それらを正しく動作させるためにフラグ u が必要です。
たとえば、文字列 𝒳 で [𝒳𝒴] を検索しましょう。
alert( '𝒳'.match(/[𝒳𝒴]/) ); // shows a strange character, like [?]
// (the search was performed incorrectly, half-character returned)
正規表現はデフォルトでサロゲートペアについて「認識していない」ため、結果は正しくありません。
正規表現エンジンは、[𝒳𝒴] を 2 つではなく 4 つの文字であると考えています。
𝒳の左半分(1)、𝒳の右半分(2)、𝒴の左半分(3)、𝒴の右半分(4)。
次のようにコードを確認できます。
for(let i=0; i<'𝒳𝒴'.length; i++) {
alert('𝒳𝒴'.charCodeAt(i)); // 55349, 56499, 55349, 56500
};
したがって、上記の例では、𝒳 の左半分を見つけて表示します。
フラグ u を追加すると、動作は正しくなります。
alert( '𝒳'.match(/[𝒳𝒴]/u) ); // 𝒳
同様の状況は、[𝒳-𝒴] などの範囲を検索する場合にも発生します。
フラグ u を追加するのを忘れると、エラーが発生します。
'𝒳'.match(/[𝒳-𝒴]/); // Error: Invalid regular expression
理由は、フラグ u がないと、サロゲートペアが 2 つの文字として認識されるため、[𝒳-𝒴] は [<55349><56499>-<55349><56500>] として解釈されるためです (すべてのサロゲートペアがそのコードに置き換えられます)。これで、範囲 56499-55349 が無効であることが簡単にわかります。開始コード 56499 が終了コード 55349 よりも大きいためです。それがエラーの正式な理由です。
フラグ u を使用すると、パターンは正しく動作します。
// look for characters from 𝒳 to 𝒵
alert( '𝒴'.match(/[𝒳-𝒵]/u) ); // 𝒴
コメント
<code>タグを使用し、複数行の場合は<pre>タグでラップし、10 行を超える場合はサンドボックスを使用してください (plnkr、jsbin、codepen…)