Heim  >  Artikel  >  Web-Frontend  >  Detaillierte Erläuterung des regulären Single-Line-Modus von JS

Detaillierte Erläuterung des regulären Single-Line-Modus von JS

php中世界最好的语言
php中世界最好的语言Original
2018-03-29 16:15:381516Durchsuche

Dieses Mal erkläre ich Ihnen ausführlich, welche Vorsichtsmaßnahmen Sie bei der Verwendung des regulären JS-Einzelzeilenmodus beachten sollten.

Regulärer Ausdruck wurde erstmals 1970 von Ken Thompson in seinem verbesserten QED-Editor implementiert. Das einfachste Metazeichen „.“ im regulären Ausdruck war jedes Zeichen außer Zeilenumbrüchen:

" ist ein regulärer Ausdruck, der mit jedem Zeichen außer übereinstimmt.

Der obige Satz stammt aus dem offiziellen Dokument von QED aus dem Jahr 1970, das möglicherweise das erste reguläre Dokument in ist Geschichte.

Warum gibt es eine solche Regel? Dies liegt daran, dass QED Dateien in Zeileneinheiten bearbeitet und das Zeilenumbruchzeichen am Ende der Zeile auch im Inhalt dieser Zeile enthalten ist. Wenn Sie beispielsweise alle einzeiligen Kommentare in einem Codeabschnitt löschen möchten, können Sie den folgenden Befehl in QED verwenden:

1,$s#//.*##
Wenn „.“ mit dem Newline-Zeichen übereinstimmen kann, dann mit dem Newline-Zeichen Das Zeichen wird ebenfalls gelöscht und führt dazu, dass diese Zeilen mit der nächsten Zeile zusammengeführt werden, was normalerweise nicht das ist, was wir wollen. Obwohl es auf dem aktuellen Betriebssystem keinen QED-Befehl zum Testen gibt, haben wir immer noch VIM, und das „.“ in VIM kann aus demselben Grund nicht mit dem Zeilenumbruchzeichen übereinstimmen.

Anders als in Node, wo das

Lesen einer Datei normalerweise das Lesen der gesamten Datei auf einmal beinhaltet, erbt Perl die Tradition vieler Linux-Befehle, die Dateien Zeile für Zeile lesen, wie folgt:

_ steht auch ein Zeilenumbruchzeichen, daher erbt Perl natürlich die QED-Regel, dass „.“ nicht mit Zeilenumbruchzeichen übereinstimmt. Aber Perl ist schließlich eine Programmiersprache und kein Editor. Seine regulären Ausdrücke müssen nicht nur mit einzeiligem Text, sondern auch mit mehrzeiligem Text übereinstimmen Da ein zeilenübergreifender Abgleich erforderlich ist, hat Perl den regulären Einzelzeilenmodus /s erfunden, der es ermöglicht, auch Zeilenumbruchzeichen abzugleichen.
while (<>) {print $_}

Die offizielle Beschreibung des /s-Modifikators in Perl, der zum Aktivieren des Einzelzeilenmodus verwendet wird, lautet „Behandle die Zeichenfolge als einzelne Zeile“. Diese „einzelne Zeile“ sollte so verstanden werden: „kann nur übereinstimmen.“ Im Normalmodus können sich Inline-Zeichen nicht über mehrere Zeilen erstrecken. Im Einzelzeilenmodus gibt Perl vor, mehrzeilige Zeichenfolgen als eine Zeile zu behandeln, und behandelt die Newline-Zeichen als Inline-Zeichen, sodass sie mit ihnen übereinstimmen können. Um es anschaulicher auszudrücken: Die folgenden drei Textzeilen

werden als „1n2n3n“ betrachtet. Dies ist die Bedeutung des einzeiligen Modus.

Aber das Schreckliche ist, dass Perl aus dem gleichen Grund (String-Variablen können mehrere Textzeilen enthalten) auch den /m-Modifikator erfunden hat, der den Mehrzeilenmodus darstellt. Die offizielle Beschreibung lautet „Behandeln Sie den String.“ als mehrere Zeilen“, ist dieses Muster
1
2
3
JavaScript

seit der Antike in den regulären Regeln enthalten. Das „mehrzeilige“ bedeutet hier: ^- und $-Metazeichen stimmen nicht mit den Positionen vor und nach den Zeilenumbruchzeichen in überein standardmäßig in der Mitte einer Zeichenfolge, d. h. Es wird davon ausgegangen, dass die Zeichenfolge immer nur eine Zeile hat und nach dem Einschalten des Mehrzeilenmodus abgeglichen werden kann.

Mit anderen Worten, der einzeilige Modus und der mehrzeilige Modus gelten für unterschiedliche Metazeichen. Personen, die mit regulären Ausdrücken noch nicht vertraut sind, werden durch die beiden scheinbar entsprechenden Begriffe „einzeiliger Modus“ und „mehrzeiliger Modus“ verwirrt sein "Modus"-Konzept, aber tatsächlich ist es mit nicht verwandten Begriffen verwirrend. Später hatte der Autor von Ruby möglicherweise das Gefühl, dass der reguläre Begriff „Einzelzeilenmodus“ nicht gut verwendet wurde, und nannte den Modus „Mehrzeilenmodus“. ist, let . * und andere reguläre Ausdrücke können mit mehreren Zeilen übereinstimmen, sodass der Modifikator auch /m verwendet (Ruby aktiviert standardmäßig den „Mehrzeilenmodus“, sodass /m nicht belegt ist). Um das Ganze noch schlimmer zu machen, ist es sogar noch chaotischer.

Später war der Python-Autor möglicherweise auch der Meinung, dass der Begriff „Einzelzeilenmodus“ vermieden werden sollte, und gab ihm daher den neuen Namen „dotall“, was bedeutet, dass der Punkt mit allen Zeichen übereinstimmen kann sehr guter Name, und später verwendete auch Java diesen Namen.

上面回顾了一下历史,解释了下单行模式的由来以及说明了下单行模式这个名字起得不好。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中文网其它相关文章!

推荐阅读:

在正则中怎么使用环视

正则表达式怎么匹配图片地址与img标签

Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung des regulären Single-Line-Modus von JS. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn