ホームページ > 記事 > ウェブフロントエンド > JS通常単行モードの詳細説明
今回は、JS の通常の単一行モードについて詳しく説明します。JS の通常の単一行モードを使用する際の 注意事項 について、実際のケースを見てみましょう。
正規表現は、1970 年に Ken Thompson によって改良された QED エディターで最初に実装されました。当時の正規表現の最も単純なメタ文字「.」は、改行を除く任意の文字に一致しました。
なぜそのようなルールがあるのでしょうか?これは、QED ではファイルを行単位で編集するため、行末の改行文字もこの行の内容に含まれるためです。たとえば、コード内の単一行コメントをすべて削除したい場合は、QED で次のコマンドを使用できます:
1,$s#//.*##
「.」が改行文字と一致する場合、改行文字も削除されます。その結果、これらの行が生成され、次の行がマージされますが、これは通常、私たちが望むものではないため、「.」が最初に発明されたときは、改行と一致しないように設計されていました。現在のオペレーティング システムにはテストできる QED コマンドはありませんが、VIM はまだ存在しており、同じ理由で VIM 内の「.」は改行文字と一致できません。
Node とは異なり、
ファイルの読み取りは通常、次のようにファイルを 1 行ずつ読み取る多くの Linux コマンドの伝統を継承しています。
while (<>) {print $_}
_ の最後には改行文字もあります。したがって、Perl 「.」は改行文字と一致しないという QED のルールを継承するのも自然です。しかし、Perl は結局のところ、エディターではなく、プログラミング言語です。その正規表現が一致する必要があるオブジェクトは、単一行のテキストだけではなく、複数行のテキストである場合もあります。したがって、その正規表現では、" ." には行間一致があります。そのため、Perl は、"." も改行文字と一致できるようにする通常の単一行モード /s を発明しました。
Perl で単一行モードを有効にするために使用される /s 修飾子の正式な説明は、「文字列を単一行として扱う」です。この「単一行」は、「.」とのみ一致します。複数行にまたがるモードではなく、通常モードでは、Perl は複数行の文字列を 1 行として扱い、改行文字をインライン文字として扱うため、「.」はそれらに一致します。もっと分かりやすく言うと、次の 3 行のテキスト 1
2
3
が「1n2n3n」の 1 行のテキストとして扱われます。これが単一行モードの意味です。
しかし、恐ろしいことに、同じ理由で (文字列変数には複数行のテキストを含めることができます)、Perl は複数行モードである /m 修飾子も発明しました。公式の説明では「文字列を複数行として扱う」となっています。このモード
JavaScriptは、古くから通常のルールに含まれています。ここでの「複数行」とは、デフォルトでは、^ および $ メタ文字が文字列の途中にある改行文字の前後の位置と一致しないことを意味します。つまり、文字列は常に 1 行のみであると見なされます。複数行モードの後で照合できます。
つまり、単一行モードと複数行モードは、異なるメタ文字に対応するものであり、正規表現を初めて使用する人は、「単一行モード」と「複数行モード」に混乱するようです。対応しているように見えますが、実際には関係のない名詞によって混同されます。 その後、Ruby の作者は、「単一行モード」という通常の用語が適切に使用されていないと感じたのか、改行文字に一致する「.」のモードを「複数行モード」と呼びました。 * など 正規表現は複数の行に一致するため、修飾子でも /m を使用するのは当然です (Ruby はデフォルトで Perl の「複数行モード」を有効にするため、/m は使用されません)。怪我を侮辱し、さらに混乱を招きます。
その後、Python の作者も「単一行モード」という用語は避けるべきだと感じたので、「dotall」という新しい名前を付けました。これは、ドットがすべての文字に一致するという意味で、非常に良い名前です。以降 Java でもこの名前が使用されます。
上面回顾了一下历史,解释了下单行模式的由来以及说明了下单行模式这个名字起得不好。V8 最近刚刚实现了一个 stage 3 的 ES 提案 https://github.com/mathiasbynens/es-regexp-dotall-flag,这个提案为 JavaScript 的正则引入了 /s 修饰符和 dotAll 属性,dotAll 属性是学了 Python 和 Java,/s 修饰符是继承了 Perl 的,这里也没必要发明一个新的修饰符比如 /d,只会让事情更复杂。/s 在 JavaScript 的具体效果是让 “.” 能匹配以前不能匹配的四个行终止符:\n(换行)、\r(回车)、\u2028(行分隔符)、\u2029(段落分隔符):
/foo/s.dotAll // true /^.{4}$/s.test("\n\r\u2028\u2029") // true
其实就是个很简单的东西,但可能一些没有接触过 JavaScript 以外的正则的同学到时候学到这个新的模式后会产生困惑,这里再澄清一下:多行模式控制的是 ^ 和 $ 的表现,单行模式控制的是 “.” 的表现,两者没有直接关系。
然而当初引入单行模式和多行模式这两个易混淆概念的 Perl 语言,已经在 Perl 6 中完全删除了这两个模式:“.” 号默认就匹配换行符,\N 可以匹配换行符除外的任意字符;^ 和 $ 始终匹配字符串的首尾,而新引入了 ^^ 和 $$ 两个元字符来匹配行的首尾。
过去我们常用的单行模式的替代品 [^] 或者 [\s\S] 也不是完全没有用了,比如在一些使用 JavaScript 正则的编辑器里(VS Code、Atom),不太可能给你提供开启单行模式的界面。不过说起编辑器里的正则功能,用 JavaScript 实现的编辑器的正则功能还是太弱了,比如不能在正则自身内部开启某些模式,比如要是在 Sublime(使用 Python 正则)里的话,在正则内部使用 (?s) 就能开启 dotall 模式,比如可以用 (?s)/\*.+?\*/ 匹配到所有的多行注释。
相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!
推荐阅读:
以上がJS通常単行モードの詳細説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。