From 33058f2b292b3a581333bdfb21b8f671898c5060 Mon Sep 17 00:00:00 2001 From: Peter Bengtsson Date: Tue, 8 Dec 2020 14:40:17 -0500 Subject: initial commit --- .../regular_expressions/assertions/index.html | 246 +++++++++++++++++++++ 1 file changed, 246 insertions(+) create mode 100644 files/ja/web/javascript/guide/regular_expressions/assertions/index.html (limited to 'files/ja/web/javascript/guide/regular_expressions/assertions') diff --git a/files/ja/web/javascript/guide/regular_expressions/assertions/index.html b/files/ja/web/javascript/guide/regular_expressions/assertions/index.html new file mode 100644 index 0000000000..e92e05b312 --- /dev/null +++ b/files/ja/web/javascript/guide/regular_expressions/assertions/index.html @@ -0,0 +1,246 @@ +--- +title: 言明 +slug: Web/JavaScript/Guide/Regular_Expressions/Assertions +tags: + - Assertions + - JavaScript + - Reference + - Regular Expressions + - regex +translation_of: Web/JavaScript/Guide/Regular_Expressions/Assertions +--- +

{{jsSidebar("JavaScript Guide")}}{{draft}}

+ +

言明には、 行や単語の始まり・終わりを示す、境界や、(先読み、後読み、条件式を含む)何らかの方法でマッチが可能なことを示す、その他のパターンが含まれます。

+ +

種類

+ +

境界型の言明

+ + + + + + + + + + + + + + + + + + + + + + + + +
文字意味
^ +

入力の先頭にマッチします。複数行フラグが true にセットされている場合は、改行文字の直後にもマッチします。例えば /^A/ は "an A" の 'A' にはマッチしませんが、"An E" の 'A' にはマッチします。

+ +
+

この文字は、文字集合パターンの先頭にある場合は異なる意味を持ちます。

+
+
$ +

入力の末尾にマッチします。複数行フラグが true にセットされている場合は、改行文字の直前にもマッチします。例えば /t$/ は "eater" の "t" にはマッチしませんが、"eat" の "t" にはマッチします。

+
\b +

単語の区切りにマッチします。これは、単語構成文字と後に続く非単語構成文字の間、または非単語構成文字と後に続く単語構成文字の間、または文字列の先頭・最後です。単語の区切りはマッチする「文字」ではありません。アンカーのように、単語の区切りはマッチした部分に含まれません。言い換えると、マッチした単語の区切りの長さは 0 です。

+ +

入力文字に "moon" を使用した例:

+ +
    +
  • /\bm/ は "m" にマッチします。これは `\b` が文字列の先頭に存在するからです。
  • +
  • /oo\b/ は "oo" にマッチしません。これは '\b' の前後に単語構成文字があるためです。
  • +
  • /oon\b/ は "oon" にマッチします。これは、文字列の終端であるためです。
  • +
  • /\w\b\w/ はどこにもマッチしないでしょう。これは、'\b' の前後に単語構成文字があるためです。
  • +
+ +

バックスペース文字 ([\b]) については文字クラスを見てください。

+
\B +

単語の区切り以外にマッチします。マッチするのは以下の場合です:

+ +
    +
  • 文字列の先頭の文字の前
  • +
  • 文字列の終端の文字の後
  • +
  • 単語内の 2 文字の間
  • +
  • 2 つの単語ではない文字の間
  • +
  • 空文字列
  • +
+ +

例えば /\B../ は "noonday" の 'oo' に、/y\B./ は "possibly yesterday" の 'ye' にマッチします。

+
+ +

その他の言明

+ +
+

? 文字は数量詞として使うことができます。

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
文字意味
x(?=y) +

先読み言明: xy が続く場合のみ x にマッチします。例えば /Jack(?=Sprat)/ は "Jack" の後に "Sprat" が続く場合のみ "Jack" にマッチします。
+ /Jack(?=Sprat|Frost)/ は "Jack" の後ろに "Sprat" または "Frost" が続く場合のみ "Jack" にマッチします。しかしながら、"Sprat" も "Frost" もマッチの結果には表れません。

+
x(?!y) +

否定先読み言明: xy が続かない場合のみ x にマッチします。例えば /\d+(?!\.)/ は後ろに小数点が続かない数値にマッチします。正規表現 /\d+(?!\.)/.exec("3.141") は "141" にマッチしますが "3.141" にはマッチしません。

+
(?<=y)x +

後読み言明: yx が続く場合のみ x にマッチします。例えば、/(?<=Jack)Sprat/ は "Jack" に続く "Sprat" のみにマッチします。 /(?<=Jack|Tom)Sprat/ は "Jack" または "Tom" に続く "Sprat" のみにマッチします。しかしながら、"Jack" も "Tom" もマッチの結果には表れません。

+
(?<!y)x +

否定後読み言明: yx が続かない場合のみ x にマッチします。例えば、/(?<!-)\d+/ は、マイナス記号のつかない数字のみにマッチします。 /(?<!-)\d+/.exec('3') は "3" がマッチします。 /(?<!-)\d+/.exec('-3') はマイナス記号に数字が続いているため、マッチが見つかりません。

+
+ +

+ +

基本的な境界型の例

+ +
// おかしい文字列を修正するために正規表現の境界を利用します。
+buggyMultiline = `tey, ihe light-greon apple
+tangs on ihe greon traa`;
+
+// 1) 文字列の最初と改行の直後のマッチを修正するために ^ を利用します。
+buggyMultiline = buggyMultiline.replace(/^t/gim,'h');
+console.log(1, buggyMultiline); // 'tey', 'tangs' を 'hey', 'hangs' に修正します。 'traa' は対象外です。
+
+// 2) テキストの末尾を修正するために $ を利用します。
+buggyMultiline = buggyMultiline.replace(/aa$/gim,'ee.');
+console.log(2, buggyMultiline); // 'traa' を 'tree' に修正します。
+
+// 3) 単語と空白の間の境界の右の文字にマッチさせるために \b を利用します。
+buggyMultiline = buggyMultiline.replace(/\bi/gim,'t');
+console.log(3, buggyMultiline); // 'ihe' を修正しますが、'light'は対象外です。
+
+// 4) エンティティの境界内の文字にマッチするために \B を利用します。
+fixedMultiline = buggyMultiline.replace(/\Bo/gim,'e');
+console.log(4, fixedMultiline); // 'greon' を修正しますが、'on' は対象外です。
+ +

^ 制御文字を利用した入力の開始へのマッチ

+ +

 ^ は、通常、単語の開始にマッチさせるために利用します。この例では、/^A/ という正規表現で 'A' で始まるフルーツを取得します。ここでの ^ は、入力の開始を示すという、たった 1 つの役割を果たしています。適切なフルーツを選択するためにアロー 関数で filter メソッドを用います。

+ +
let fruits = ["Apple", "Watermelon", "Orange", "Avocado", "Strawberry"];
+
+// /^A/ 正規表現で 'A' で始まるフルーツを選択します。
+// ここでの'^' 制御記号は「入力の開始にマッチする」という 1 つの役割だけで利用されています。
+
+let fruitsStartsWithA = fruits.filter(fruit => /^A/.test(fruit));
+console.log(fruitsStartsWithA); // [ 'Apple', 'Avocado' ]
+ +

2 番目の例での ^ は、入力の開始へのマッチと、グル―プで用いられた場合の文字集合の否定または補集合という、両方で利用されています。

+ +
let fruits = ["Apple", "Watermelon", "Orange", "Avocado", "Strawberry"];
+
+// /^[^A]/ という正規表現で 'A' で始まらないフルーツを選択します。
+// この例では、'^' 制御記号は 2 つの意味を表しています。
+// 1) 入力の開始にマッチ
+// 2) [^A]という文字集合の否定または補集合: 
+// つまり、角括弧で囲まれたものでないあらゆるものにマッチします
+
+let fruitsStartsWithNotA = fruits.filter(fruit => /^[^A]/.test(fruit));
+
+console.log(fruitsStartsWithNotA); // [ 'Watermelon', 'Orange', 'Strawberry' ]
+ +

単語の境界にマッチ

+ +
let fruitsWithDescription = ["Red apple", "Orange orange", "Green Avocado"];
+
+// 単語の終わりに 'en' または 'ed' を含む記述を選択します。
+let enEdSelection = fruitsWithDescription.filter(descr => /(en|ed)\b/.test(descr));
+
+console.log(enEdSelection); // [ 'Red apple', 'Green Avocado' ]
+ +

先読み言明

+ +
// JS Lookahead assertion x(?=y)
+
+let regex = /First(?= test)/g;
+
+console.log('First test'.match(regex)); // [ 'First' ]
+console.log('First peach'.match(regex)); // null
+console.log('This is a First test in a year.'.match(regex)); // [ 'First' ]
+console.log('This is a First peach in a month.'.match(regex)); // null
+ +

基本的な否定先読み言明

+ +

例えば、/\d+(?!\.)/ は小数点が後に続かない数値にだけマッチします。/\d+(?!\.)/.exec('3.141') は "141" にマッチしますが、 "3" にはマッチしません。

+ +
console.log(/\d+(?!\.)/g.exec('3.141')); // [ '141', index: 2, input: '3.141' ]
+ +

言明と範囲における '?!' の組み合わせの異なる意味での利用

+ +

 ?! の組み合わせを利用するとき、言明 /x(?!y)/ 範囲 [^?!]では異なる意味を持ちます。

+ +
let orangeNotLemon = "Do you want to have an orange? Yes, I do not want to have a lemon!";
+
+// 言明 /x(?!y)/ と範囲 /[^?!]/ では '?!' の組み合わせの利用は異なる意味を持ちます。
+let selectNotLemonRegex = /[^?!]+have(?! a lemon)[^?!]+[?!]/gi
+console.log(orangeNotLemon.match(selectNotLemonRegex)); // [ 'Do you want to have an orange?' ]
+
+let selectNotOrangeRegex = /[^?!]+have(?! an orange)[^?!]+[?!]/gi
+console.log(orangeNotLemon.match(selectNotOrangeRegex)); // [ ' Yes, I do not want to have a lemon!' ]
+ +

後読み言明

+ +
let oranges = ['ripe orange A ', 'green orange B', 'ripe orange C',];
+
+let ripe_oranges = oranges.filter( fruit => fruit.match(/(?<=ripe )orange/));
+console.log(ripe_oranges); // [ 'ripe orange A ', 'ripe orange C' ]
+ +

仕様

+ + + + + + + + + + + + + + +
仕様策定状況コメント
{{SpecName('ESDraft', '#sec-assertion', 'RegExp: Assertions')}}{{Spec2('ESDraft')}}
+ +

ブラウザサポート

+ +
+ + +

{{Compat("javascript.builtins.RegExp.assertions")}}

+
+ +

関連情報

+ + -- cgit v1.2.3-54-g00ecf