序文
最近、一部の場所でのJavaScriptの規則性のパフォーマンスは、他の言語やツールのパフォーマンスとは多少異なり、比較的代替であることがわかりました。あなたがそれらを書くことはほとんど不可能であり、あなたは私が以下に述べたルールをほとんど使用することはほとんどできませんが、結局それらを理解することは良いことです。
この記事のコードの例は、ES5と互換性のあるJavaScript環境で実行されます。つまり、IE9の前のバージョンのパフォーマンス、FX4の周りのバージョンなどは、以下に言及したものとは異なる可能性があります。
1。空の文字クラス
[]を含まないキャラクタークラスは、空のempty char classクラスと呼ばれます。他の言語では、他の言語ではこの執筆方法が違法であり、すべてのドキュメントやチュートリアルが違法な構文について話していないため、他の人がそれを呼ぶのを聞いたことがないと思います。他の言語やツールがこのエラーをどのように報告するかを示しましょう。
$ echo | grep '[]' grep:unmacted [or [^$ echo | sed '/[]/' sed:-e式#1、キャラクター4:未終端のアドレス正規表現$ echo | awk '/[]/' awk:cmd。行:1: /[] /awk:cmd。ライン:1: ^未終端のregexpawk:cmd。行:1:エラー:無音[または[^:/[] // $ echo | perl -ne '/[]/'比類のない[Regex; <でマークされます - ここでm/ [<-<-here]/ at -e line 1. $ echo | ruby -ne '/[]/' -E:1:空のchar -class:/[]/$ python -c 'import re; re.match( "[] []" ""、 "")' traceback(最新のコールlast):file "<string>"、in <module> file "e:/python/lib/re.py"、file 137、in mate return 137、 "e:/python/lib/re.py"、行244、_compile raise error、v#invalid expressionsre_constants.error:正規表現の予期しない終わり
JavaScriptでは、空のキャラクタークラスは法的規則的なコンポーネントですが、その効果は「決して一致しない」、つまりすべてが失敗するでしょう。それは(empty negative lookahead)(?!)の影響と同等です。
js> "whating/n" .match(/[]/g)// null文字クラス、nulljs> "whation/n" .match(/(?!)/g)// null negation forwardを見回すと、nullと一致することはありません
明らかに、この種のことはJavaScriptでは役に立たない。
2。空の文字クラスを無効にします
この名詞は「自己作成」であり、上記の空のキャラクタークラスに似ていたため、文字を含まないネガティブキャラクタークラスもネガティブな空のチャークラスまたは空のネガティブチャークラスと呼ばれます。この執筆方法は、他の言語でも違法です。
$ echo | grep '[^]' grep:unmacted [or [^$ echo | sed '/[^]/' sed:-e式#1、キャラクター5:非終了アドレス正規表現$ echo | awk '/[^]/' awk:cmd。行:1: /[^] /awk:cmd。ライン:1: ^未終端のregexpawk:cmd。行:1:エラー:無音[または[^:/] // $ echo | perl -ne '/[^]/'比類のない[Regex;マーク< - ここでm/ [< - here ^]/ at -e line 1. $ echo | ruby -ne '/[^]/' -E:1:空のchar -class:/[^]/$ python -c 'import re; re.match( "[^]"、 "")' traceback(file "<string>"、in <odule> file "e:/pile.lib/re.py"、in mate 137、in mate 137、in <module> "e:/python/lib/re.py"、行244、_compile raise error、v#invalid expressionsre_constants.error:予期しない正規表現$ $
JavaScriptでは、null文字クラスを否定することは、合法的な通常のコンポーネントです。その効果は、null文字クラスの効果の正反対です。 Newline "/n"を含むあらゆるキャラクターと一致させることができます。つまり、一般的な[/s/S]および[/w/W]に相当します。
js> "Anything/n" .match(/[^]/g)// neizontal Charatere Class、任意のキャラクター["w"、 "h"、 "a" t "、" e "、" v "、" e "、" r "、"/n "] js>" whatid/n ".match(/s/s "t"、 "e"、 "v"、 "e"、 "r"、 "/n"]
キャラクタークラスには一致するキャラクターが必要なため、「永続的な一致する規則性」と呼ばれることはできません。ターゲット文字列が空であるか、左の規則性によって消費されている場合、たとえば、試合は失敗します。
js> /abc [^] /.test("abc ")// cの後に文字はありません。真の「永続的なマッチングルール」を知りたい場合は、以前に翻訳した記事をチェックしてください:「空の」ルール
3. []]および[^]]
これは比較的単純です。つまり、Perlの正規表現と他のLinuxコマンドのいくつかの[]コマンドでは、文字クラスが左の正方形の[]]の直後に右側の四角いブラケットが含まれている場合、右の正方形のブラケットは通常の文字と見なされます。 JavaScriptでは、この規則性は空のキャラクタークラスに続いて右の正方形のブラケットが続き、空の文字クラスは何も一致しません.[^]]は似ています。JavaScriptでは、任意の文字(負のヌル文字クラス)と一致し、その後に"a]","b]"などの正方形のブラケットが続きますが、他の言語では、非]文字と一致します。
$ perl -e 'print "]" =〜/[]]/' 1 $ js -e 'print(/[]]/。test( "]" "))' false $ perl -e 'print" x "=〜/[^]]/' 1 $ js -e 'print(/[^]]/。test(" x ")' false false
4. $アンカーポイント
一部の初心者は、$が新しいライン文字"/n"と一致していると考えています。これは大きな間違いです。 $はゼロ幅のアサーションであり、実際のキャラクターと一致することは不可能であり、1つの位置のみを一致させることができます。私が話したい違いは、非マルチラインモードで起こります:非マルチラインモードでは、$が最後のキャラクターにちなんでポジションと一致していないと思うかもしれません。実際、それほど単純ではありません。他のほとんどの言語では、ターゲット文字列の最後の文字がnewline文字"/n"である場合、$もnewlineの前の位置と一致します。つまり、最後のラインブレークの左側と右側の2つの位置と一致します。多くの言語には、2つの表記法 /zと /zがあります。それらの違いを知っている場合、他の言語(Perl、Python、Php、Java、C#...)で、非マルチラインモードの$は /zに相当しますが、JavaScriptでは、非マルチラインモードでは /Zに相当します(最後の位置にのみ一致します。 Rubyは、マルチラインモードにデフォルトであるため、特別なケースです。 $ in multi-lineモードは、各新しいラインの前の位置と一致します。もちろん、最後に表示される可能性のあるラインブレークも含まれます。 Yu Shengの本「通常のガイドライン」もこれらのポイントについて語っています。
$ perl -e 'print "whathing/n" = 〜s/$/$/$/$ // rg' //グローバル置換任意の文字//ラインブレークの前の位置は、ラインブレークの代替キャラクターに置き換えられます。
5。DOTメタカラクター「。」
JavaScriptの正規表現では、DOT Metacharacter「」。 4つのラインターミネーター( /rキャリッジリターン、 /n-line newline、 /u2028-lineセパレーター、 /u2029-paragraphセパレーター)を除くすべての文字を一致させることができますが、他の一般的な言語では、線のnewline /nのみが除外されます。
6。前向きに引用
私たちは皆、レギュラーにバックリファレンス、つまり、以前のキャプチャグループで一致した文字列へのバックスラッシュ +番号の参照があることを知っています。目的は、再び一致するか、交換結果として(/ $になる)ことです。しかし、参照されたキャプチャグループが開始されていない場合(左ブラケットが境界が囲まれている)、バックリファレンスを使用しているという特別なケースがあります。たとえば、通常の/(/2(a)){2}/ 、(a)は2番目のキャプチャグループですが、その一致する結果は左側で使用されます。通常の一致が左から右に一致することを知っています。これは、このセクションのタイトルフォワードリファレンスの起源です。それは厳格な概念ではありません。それで、あなたはそれについて考えます、次のJavaScriptコードは何を返しますか:
js>/(/2(a)){2}/。exec( "aaa")???この質問に答える前に、他の言語のパフォーマンスを見てみましょう。同様に、他の言語では、このように書くことは基本的に無効です。
$ echo aaa | grep '(/2(a)){2}' grep:無効なバックリファレンス$ echo aaa | sed -r '/(/2(a)){2}/' sed:-e式#1、文字12:違法なリファレンス$ echo aaa | awk '/(/2(a)){2}/' $ echo aaa | perl -ne 'print/(/2(a)){2}/' $ echo aaa | ruby -ne '印刷$ _ =〜/(/2(a)){2}/' $ python -c 'import re; print re.match( "(/2(a)){2}"、 "aaa")'awkにはこの背景をサポートしていないため、AWWにエラーはありません。 /2はASCIIコード2の文字として解釈されます。ただし、Perl Ruby Pythonにはエラーはありません。このデザインがPerlによって学ぶべき理由はわかりませんが、効果は同じです。この場合、うまく一致することは不可能です。
JavaScriptでは、エラーを報告しないだけでなく、それを正常に一致させることもできます。答えがあなたが今考えたものと同じであることを見てみましょう:
js> /(/2(a)){2 }/.exec( "aaa") [" aa "、" a "、" a "]] execメソッドによって結果が返されることを忘れないようにするために、私に言ってください。最初の要素は、完全な一致する文字列、つまりRegExp["$&"]であり、その後、各キャプチャグループのコンテンツが一致します。つまり、 RegExp.$1およびRegExp.$2.なぜマッチングは成功できるのですか?マッチングプロセスは何ですか?私の理解は次のとおりです。
最初に、最初のキャプチャグループ(左端の左括弧)に入ります。最初の有効な一致は /2ですが、この時点で2番目のキャプチャグループ(a)はまだラウンドにありませんRegExp.$2はまだundefined 。ポイントは、試合が成功したことです。続けて、2番目のキャプチャグループ(a)はターゲット文字列の最初のAとRegExp.$2は「a」に割り当てられ、最初のキャプチャグループは端がRegExp.$1します(右端の右端の右端の右端の右端の右端の右端。次に、Quantifier {2}があります。つまり、ターゲット文字列の最初のAの後、通常の(/2(a))の新しいラウンドが開始されます。キーポイントはここにありますRegExp.$2の値は、 /2の一致の値であるか、「A」の最初のラウンドの最後に割り当てられた値です。答えは、「いいえ」、 RegExp.$1とRegExp.$2 undefinedとしてクリアされ、 /1と /2は初めてと同じで、空の文字と一致することに成功します(書かれているかどうかにかかわらず、効果がないかどうかに相当)。ターゲット文字列の2番目のaは正常に一致し、 RegExp.$1 RegExp["$&"] RegExp.$2 「A」になります。
Firefoxの以前のバージョン(3.6)では、数量詞の再試合は既存のキャプチャされたグループの値をクリアしません。つまり、2回目の試合では、 /2は2番目のAと一致します。
js> /(/2(a)){2 }/.exec("aaa") ["aaa"、 "a"]]さらに、キャプチャグループの終わりは、閉鎖ブラケットが閉じているかどうかによって異なります。たとえば、/(a/1){3}/。最初のキャプチャグループは /1が使用されたときに一致し始めましたが、まだ終了していません。これも前方の参照であるため、 /1の一致はまだ空です:
js> /(a/1) {3 }/.exec( "aaa") [" aaa "、" a "]]別の例:
js> /(?:( o)(o)(b)(a)(r)(r))Nexec("foobar") ["foobar"、未定義、未定義、未定義、「b "、" a "、" r "]] *量子です。マッチングの最初のラウンドの後:1ドルは「F」、2ドルは「O」、3ドルは「O」、4ドルは未定義、5ドルはundefinedで、6ドルはundefinedです。
試合の第2ラウンドの開始時:すべてのキャプチャされた値はundefinedにリセットされます。
第2ラウンドの試合の後:$ 1はundefined 、2ドルはundefined 、3ドルはundefined 、4ドルは「B」、5ドルは「A」、6ドルは「R」です。
&は「Foobar」として割り当てられ、試合は終了します。
要約します
上記は、JavaScriptの規則性と他の言語の違いを要約するコンテンツ全体です。この記事の内容が、すべての人の勉強と仕事に役立つことを願っています。