角括弧 […]
内の複数の文字または文字クラスは、「指定された文字のいずれかを検索する」ことを意味します。
集合
たとえば、[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…)