文字クラス

実践的なタスクを考えてみましょう – "+7(903)-123-45-67" という電話番号があり、その文字列のすべての数字を見つける必要があります。他の文字に興味はありません。

文字クラスは集合から任意の記号にマッチする特別な表記法です。

例えば、“数字” クラスがあります。それは \d と書きます。それを正規表現のパターンに入れ検索すると、任意の数字がそれにマッチします。

例えば、正規表現 /\d/ は1つの数字を探します:

let str = "+7(903)-123-45-67";

let reg = /\d/;

alert( str.match(reg) ); // 7

上の例では、正規表現はグローバルではありません。なので、最初のマッチだけを探します。

すべての数字を探すために g フラグを追加しましょう:

let str = "+7(903)-123-45-67";

let reg = /\d/g;

alert( str.match(reg) ); // マッチした配列: 7,9,0,3,1,2,3,4,5,6,7

最もよく使われるクラス: \d \s \w

先程は数字のための文字クラスでした。同様に他の文字クラスがあります。

最も使われるのは:

\d (“d” は “digit” より)
数字: 0 から 9 の文字です。
\s (“s” は “space” より)
スペース記号: スペース、タブ、改行が含まれます。
\w (“w” は “word” より)
“言葉” の文字: 英語アルファベットの文字または数字またはアンダースコア。 非英語の文字(キリル文字やヒンディー語など)は \w に属しません。

例えば、\d\s\w"1 Z" のように、数字のあとに空白文字、単語文字が続く文字列を意味します。

正規表現は通常の記号と文字クラス両方を含む場合があります。

例として、CSS\dCSS のあとに数字が続く文字列にマッチします。:

let str = "CSS4 is cool";
let reg = /CSS\d/

alert( str.match(reg) ); // CSS4

また、多くの文字クラスを使うこともできます:

alert( "I love HTML5!".match(/\s\w\w\w\w\d/) ); // 'HTML5'

マッチ(各文字クラスは結果文字に対応します):

単語境界: \b

単語境界 \b – は特別な文字クラスです。

これは文字を表すのではなく、文字の境界を表します。

例えば、 \bJava\bHello, Java! という文字列の Java とマッチしますが、Hello, JavaScript! という文字列にはマッチしません。:

alert( "Hello, Java!".match(/\bJava\b/) ); // Java
alert( "Hello, JavaScript!".match(/\bJava\b/) ); // null

通常、文字クラスは結果の文字(単語や数字のような)を意味するので、ある意味では、境界は “ゼロ幅” を持ちますが、この場合はそうではありません。

境界はテストです。

正規表現エンジンが検索を行っているとき、マッチを見つけるために文字列に沿って移動しています。各文字列の位置で、パターンを検索しようとします。

パターンに \b が含まれている場合、文字列の位置が次の条件のいずれかを満たしているか検査します:

  • 文字列が開始し、最初の文字が \w である。
  • 文字列が終わり、最後の文字が \w である。
  • 文字列の内側: 片方が \w で、もう一方が \w でない。

例えば、Hello, Java! の文字列で \b にマッチする位置は次の通りです:

したがって、\bHello\b\bJava\b はマッチしますが、\bHell\b (l のあとに単語境界がないため) と Java!\b (感嘆符は \w でマッチする文字ではないので、単語境界がありません)はマッチしません。

alert( "Hello, Java!".match(/\bHello\b/) ); // Hello
alert( "Hello, Java!".match(/\bJava\b/) );  // Java
alert( "Hello, Java!".match(/\bHell\b/) );  // null
alert( "Hello, Java!".match(/\bJava!\b/) ); // null

\b は検索エンジンに境界をテストさせます。それにより、Java\b は単語境界が続く場合にのみ Java を検出しますが、結果には文字を追加しないことに改めて留意しましょう。

通常、スタンドアロンの英単語を見つけるのに \b を使います。そのため、"Java" が必要な場合、\bJava\b は正確にスタンドアロンの単語を見つけ、"JavaScript" の一部であるときは無視します。

別の例: 正規表現 \b\d\d\b はスタンドアロンの 2桁の数字を探します。つまり、前後の \d\d\w (もしくは文字列の始め/終わり)とは異なる記号でなければなりません。

alert( "1 23 456 78".match(/\b\d\d\b/g) ); // 23,78
単語境界は英語以外のアルファベットでは機能しません

単語境界チェック \b\w と他のものとの間の境界をテストします。しかし、 \w は英語文字(もしくは数字かアンダースコア)を意味するので、他の文字(キリル文字や象形文字など)の場合は機能しません。

逆のクラス

すべての文字クラスには “逆のクラス” があります。それは同じ文字ですが大文字で表されます。

“逆” は、他のすべての文字にマッチすることを意味します。例えば:

\D
非数字: \d 以外の任意の字です。例えば文字です。
\S
非スペース: \s 以外のすべての文字です。例えば文字です。
\W
非単語文字: \w 以外の文字。
\B
非境界: \b と逆のテストです。

チャプターの先頭では、電話番号 +7(903)-123-45-67 からすべての数字を取得する方法を見ました。文字列から “純粋な” 電話番号を取得してみましょう。:

let str = "+7(903)-123-45-67";

alert( str.match(/\d/g).join('') ); // 79031234567

代わりの方法は、文字列から非数字を見つけ削除することです:

let str = "+7(903)-123-45-67";

alert( str.replace(/\D/g, "") ); // 79031234567

空白は通常の文字です

正規表現は空白を含む場合があることに注意してください。空白は普通の文字のように扱われます。

通常、私たちは空白にはあまり注意を払っていません。我々にとって文字列 1-51 - 5 はほぼ同じです。

しかし、正規表現は空白を考慮しなければ期待通りに動作しません。

ダッシュで分離されている数字を見つけましょう。:

alert( "1 - 5".match(/\d-\d/) ); // null, マッチしません!

これは正規表現の中に空白を追加して修正したものです:

alert( "1 - 5".match(/\d - \d/) ); // 1 - 5, これは動作します

もちろん、空白はそれらを探す場合にだけ必要です。余分な空白は(単に別の他のとゆうな文字と同じように)マッチするのを妨げます。:

alert( "1-5".match(/\d - \d/) ); // null, 文字列 1-5 には空白がないからです

つまり、正規表現ではすべての文字が重要です。空白もです。

ドットは任意の文字です

ドット "."改行を除く任意の文字 にマッチする特別な文字クラスです。

例:

alert( "Z".match(/./) ); // Z

また正規表現の中にある場合:

let reg = /CS.4/;

alert( "CSS4".match(reg) ); // CSS4
alert( "CS-4".match(reg) ); // CS-4
alert( "CS 4".match(reg) ); // CS 4 (空白も文字です)

ドットは “任意の文字” を意味しますが、 “文字の欠如” ではないことに注意してください。それにマッチする文字が必要です::

alert( "CS4".match(/CS.4/) ); // null, ドットに対する文字がないのでマッチしません

サマリ

文字クラスを説明しました:

  • \d – 数字
  • \D – 非数字
  • \s – スペース記号、タブ、改行
  • \S\s 以外
  • \w – 英語文字、数字、アンダースコア '_'
  • \W\w 以外
  • '.' – 改行以外の任意の文字

バックスラッシュやドットのような特別な意味を持つ文字を検索したい場合、バックスラッシュ \. でエスケープする必要があります。

正規表現は改行 \n と言った特別な文字も含むことに注意してください。 他の文字が使用されているので、文字クラスとの競合はありません。

タスク

時間にはフォーマット hours:minutes があります。09:00 のように時と分は両方とも2桁の数字です。

文字列 Breakfast at 09:00 in the room 123:456. で時間を見つける正規表現を作成してください。

P.S. このタスクではまだ時間の正しさをチェックをする必要はありません。なので、25:99 も有効な結果です。 P.P.S 正規表現は 123:456 にはマッチしないでください。

解答: \b\d\d:\d\d\b.

alert( "Breakfast at 09:00 in the room 123:456.".match( /\b\d\d:\d\d\b/ ) ); // 09:00
チュートリアルマップ

コメント

コメントをする前に読んでください…
  • 自由に記事への追加や質問を投稿をしたり、それらに回答してください。
  • 数語のコードを挿入するには、<code> タグを使ってください。複数行の場合は <pre> を、10行を超える場合にはサンドボックスを使ってください(plnkr, JSBin, codepen…)。
  • 記事の中で理解できないことがあれば、詳しく説明してください。