Maison interface Web js tutoriel Comment comprendre correctement le retour en arrière des expressions régulières en js

Comment comprendre correctement le retour en arrière des expressions régulières en js

Mar 30, 2018 pm 01:56 PM
javascript 表达式

Cette fois, je vais vous montrer comment comprendre correctement le traçage des expressions régulières en js, et quelles sont les précautions pour utiliser correctement le traçage des expressions régulières en js. Voici des cas pratiques. . , jetons un coup d'oeil.

Dans l'implémentation d'expressions régulières, le backtracking est un élément fondamental du processus de correspondance, et c'est la raison pour laquelle les expressions régulières sont si utiles et puissantes. Cependant, le retour en arrière est coûteux en calcul et peut entraîner une perte de contrôle si la conception est erronée. Le retour en arrière est le seul facteur qui affecte les performances globales. Comprendre son fonctionnement et comment réduire la fréquence d'utilisation peut être la clé pour écrire des expressions régulières efficaces

Lorsqu'une expression régulière analyse la chaîne cible, à partir de Scan. les composants de l'expression régulière un par un de gauche à droite, en testant si une correspondance peut être trouvée à chaque position. Pour chaque quantificateur et branche, il faut décider comment procéder. S'il s'agit d'un quantificateur (tel que *, +? ou {2,}), alors l'expression régulière doit déterminer quand essayer de faire correspondre plus de caractères si elle rencontre une branche (via l'opérateur |), alors l'expression régulière doit ; commencez par ceux-ci Choisissez l’une des options à essayer.

Lorsque l'expression régulière prend une décision comme celle-ci, elle se souvient d'une autre option pour une utilisation ultérieure si nécessaire. Si le schéma sélectionné correspond avec succès, l'expression régulière continuera à analyser le modèle d'expression régulière et si les autres correspondances réussissent également, la correspondance se termine. Cependant, si l'option choisie ne parvient pas à trouver de correspondance, ou si les correspondances suivantes échouent, l'expression régulière reviendra au dernier point de décision et sélectionnera l'une des options restantes. Continuez ce processus jusqu'à ce qu'une correspondance soit trouvée ou que toutes les permutations possibles de quantificateurs et d'options de branchement aient été essayées, puis le processus est abandonné, puis déplacé vers le caractère suivant au début du processus, et le processus est répété.

Par exemple, le code ci-dessous montre comment ce processus gère les branches via le backtracking.

/h(ello|appy) hippo/.test("hello there, happy hippo");
Copier après la connexion

La ligne d'expression régulière ci-dessus est utilisée pour faire correspondre "hello hippo" ou "happy hippo". Au début du test, nous recherchions un h. La première lettre de la chaîne cible était h, et nous l'avons trouvée immédiatement. Ensuite, la sous-expression (ello|appy) propose deux options de traitement. L'expression régulière sélectionne l'option la plus à gauche (la sélection de branche s'effectue toujours de gauche à droite), vérifie si ello correspond au caractère suivant de la chaîne, c'est le cas, puis l'expression régulière correspond aux espaces suivants.

Cependant, l'expression régulière "se retrouve dans une impasse" lors du prochain match, car le h dans hippo ne peut pas correspondre à la lettre t suivante dans la chaîne. L'expression régulière ne peut pas abandonner à ce stade car elle n'a pas encore essayé toutes les options, elle revient donc au dernier point de contrôle (après avoir fait correspondre le h initial) et essaie de faire correspondre la deuxième option de branche. Mais comme la correspondance n'a pas abouti et qu'il n'y a plus d'options, l'expression régulière a estimé que la correspondance à partir du premier caractère de la chaîne ne réussirait pas, elle a donc recommencé la recherche à partir du deuxième caractère. L’expression régulière n’a pas trouvé h, elle a donc continué à regarder en arrière jusqu’à trouver la 14ème lettre, qui correspondait au h heureux. Ensuite, l'expression régulière se ramifie à nouveau, et cette fois ello ne parvient pas à correspondre, mais dans la deuxième branche après un retour en arrière, elle correspond à la chaîne entière "happy hippo" et la correspondance réussit.

Comme autre exemple, le code suivant démontre le retour en arrière avec des quantificateurs répétés.

var str = "<p>Para 1.</p>" +"<img src=&#39;smiley.jpg&#39;>" +"<p>Para 2.</p>" +"<p>p.</p>";
/<p>.*<\/p>/i.test(str);
Copier après la connexion

L'expression régulière correspond d'abord aux trois lettres

au début de la chaîne, puis à .*. Le point signifie correspondre à n'importe quel caractère à l'exception des caractères de nouvelle ligne, et l'astérisque, un quantificateur « gourmand », signifie répéter zéro ou plusieurs fois pour correspondre autant de fois que possible. Comme il n'y a pas de nouvelle ligne dans la chaîne cible, l'expression régulière correspondra à la totalité de la chaîne restante ! Cependant, comme il y a plus de contenu à faire correspondre dans le modèle d'expression régulière, l'expression régulière essaie de correspondre à <. Puisque la correspondance à la fin de la chaîne échoue, nous revenons en arrière un caractère à la fois et continuons à essayer de faire correspondre < jusqu'à ce que l'expression régulière revienne à la position

Ensuite, il essaie de faire correspondre / (en évitant la barre oblique inverse), qui correspond avec succès, puis p, qui ne correspond pas. L'expression régulière continue de revenir en arrière et répète ce processus jusqu'à ce qu'elle corresponde enfin à

à la fin du deuxième paragraphe. Pour renvoyer une correspondance réussie, vous devez numériser du début du premier paragraphe à la fin du dernier paragraphe, ce qui peut ne pas être le résultat souhaité.

Changer le quantificateur « gourmand » * dans l'expression régulière par le quantificateur « paresseux » (alias « non gourmand ») * pour correspondre à un seul paragraphe. Le retour en arrière pour les quantificateurs « paresseux » fonctionne de la manière opposée. Lorsque l'expression régulière /

.*?

/ avance vers .*?, elle tente d'abord de les ignorer toutes, puis continue de faire correspondre

.

这样做是因为*?匹配零次或多次,尽可能少重复,尽可能少意味着可以重复零次。但是,当随后的<在字符串的这一点上匹配失败时,正则表达式回溯并尝试下一个最小的字符数:1个。正则表达式继续像这样向前回溯到第一段的末尾,在那里量词后面的<\/p>得到完全匹配。

如果目标字符串只有一个段落,那么此正则表达式的“贪婪”版本和“懒惰”版本是等价的,但尝试匹配的过程不同。

当一个正则表达式占用浏览器几秒甚至更长时间时,问题原因很可能是回溯失控。为说明此问题,给出下面的正则表达式,它的目标是匹配整个HTML文件。此表达式被拆分成多行是为了适合页面显示。与其他正则表达式不同,JavaScript在没有选项时可使点号匹配任意字符,包括换行符,所以此例中以[\s\S]匹配任意字符。

/<html>[\s\S]*?<head>[\s\S]*?<title>[\s\S]*?<\/title>[\s\S]*?<\/head>
[\s\S]*?<body>[\s\S]*?<\/body>[\s\S]*?<\/html>/
Copier après la connexion

此正则表达式匹配在正常HTML 字符串时工作良好,但当目标字符串缺少一个或多个标签时,就会变得十分糟糕。例如标签缺失,最后一个[\s\S]*?将扩展到字符串的末尾,因为在那里没有发现标签,然后正则表达式将查看此前的[\s\S]*?队列记录的回溯位置,使它们进一步扩大。正则表达式尝试扩展倒数第二个[\s\S]*?—用它匹配标签,就是此前匹配过正则表达式模板<\/body>的那个标签,然后继续查找第二个标签,直到字符串的末尾。当所有这些步骤都失败时,倒数第三个[\s\S]*?将被扩展,直至字符串的末尾,依此类推。

此类问题的解决办法在于尽可能具体地指出分隔符之间的字符匹配形式,如模板“.*?”用于匹配双引号包围的一个字符串。用更具体的[^"\rn]*取代过于宽泛的.*?就去除了回溯时可能发生的几种情况,如尝试用点号匹配引号,或者扩展搜索超出预期范围。

在HTML 的例子中解决办法不是那么简单。不能使用否定字符类型,如用[^<]替代[\s\S],因为在搜索过程中可能会遇到其他类型的标签。但是,可以通过重复一个非捕获组来达到同样效果,它包含一个回溯(阻塞下一个所需的标签)和[\s\S](任意字符)元序列。这样可以确保中间位置上查找的每个标签都会失败。然后,更重要的是,[\s\S]模板在回溯过程中阻塞的标签在被发现之前不能被扩展。应用此方法后对正则表达式的最终修改如下:

/<html>(?:(?!<head>)[\s\S])*<head>(?:(?!<title>)[\s\S])*<title>
(?:(?!<\/title>)[\s\S])*<\/title>(?:(?!<\/head>)[\s\S])*<\/head>
(?:(?!<body>)[\s\S])*<body>(?:(?!<\/body>)[\s\S])*<\/body>
(?:(?!<\/html>)[\s\S])*<\/html>/
Copier après la connexion

虽然这样做消除了潜在的回溯失控,并允许正则表达式在匹配不完整HTML字符串失败时的使用时间与文本长度呈线性关系,但是正则表达式的效率并没有提高。像这样为每个匹配字符进行多次前瞻,缺乏效率,而且成功匹配过程也相当慢。匹配较短字符串时使用此方法相当不错,而匹配一个HTML 文件可能需要前瞻并测试上千次。

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

正则全局匹配模式g修饰符的使用详解

正则表达式小结(实战归纳)

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

AI Hentai Generator

AI Hentai Generator

Générez AI Hentai gratuitement.

Article chaud

R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Meilleurs paramètres graphiques
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Comment réparer l'audio si vous n'entendez personne
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Comment déverrouiller tout dans Myrise
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Comment mettre en œuvre un système de reconnaissance vocale en ligne à l'aide de WebSocket et JavaScript Comment mettre en œuvre un système de reconnaissance vocale en ligne à l'aide de WebSocket et JavaScript Dec 17, 2023 pm 02:54 PM

Comment utiliser WebSocket et JavaScript pour mettre en œuvre un système de reconnaissance vocale en ligne Introduction : Avec le développement continu de la technologie, la technologie de reconnaissance vocale est devenue une partie importante du domaine de l'intelligence artificielle. Le système de reconnaissance vocale en ligne basé sur WebSocket et JavaScript présente les caractéristiques d'une faible latence, d'un temps réel et d'une multiplateforme, et est devenu une solution largement utilisée. Cet article explique comment utiliser WebSocket et JavaScript pour implémenter un système de reconnaissance vocale en ligne.

WebSocket et JavaScript : technologies clés pour mettre en œuvre des systèmes de surveillance en temps réel WebSocket et JavaScript : technologies clés pour mettre en œuvre des systèmes de surveillance en temps réel Dec 17, 2023 pm 05:30 PM

WebSocket et JavaScript : technologies clés pour réaliser des systèmes de surveillance en temps réel Introduction : Avec le développement rapide de la technologie Internet, les systèmes de surveillance en temps réel ont été largement utilisés dans divers domaines. L'une des technologies clés pour réaliser une surveillance en temps réel est la combinaison de WebSocket et de JavaScript. Cet article présentera l'application de WebSocket et JavaScript dans les systèmes de surveillance en temps réel, donnera des exemples de code et expliquera leurs principes de mise en œuvre en détail. 1. Technologie WebSocket

Comment mettre en œuvre un système de réservation en ligne à l'aide de WebSocket et JavaScript Comment mettre en œuvre un système de réservation en ligne à l'aide de WebSocket et JavaScript Dec 17, 2023 am 09:39 AM

Comment utiliser WebSocket et JavaScript pour mettre en œuvre un système de réservation en ligne. À l'ère numérique d'aujourd'hui, de plus en plus d'entreprises et de services doivent fournir des fonctions de réservation en ligne. Il est crucial de mettre en place un système de réservation en ligne efficace et en temps réel. Cet article explique comment utiliser WebSocket et JavaScript pour implémenter un système de réservation en ligne et fournit des exemples de code spécifiques. 1. Qu'est-ce que WebSocket ? WebSocket est une méthode full-duplex sur une seule connexion TCP.

Comment utiliser JavaScript et WebSocket pour mettre en œuvre un système de commande en ligne en temps réel Comment utiliser JavaScript et WebSocket pour mettre en œuvre un système de commande en ligne en temps réel Dec 17, 2023 pm 12:09 PM

Introduction à l'utilisation de JavaScript et de WebSocket pour mettre en œuvre un système de commande en ligne en temps réel : avec la popularité d'Internet et les progrès de la technologie, de plus en plus de restaurants ont commencé à proposer des services de commande en ligne. Afin de mettre en œuvre un système de commande en ligne en temps réel, nous pouvons utiliser les technologies JavaScript et WebSocket. WebSocket est un protocole de communication full-duplex basé sur le protocole TCP, qui peut réaliser une communication bidirectionnelle en temps réel entre le client et le serveur. Dans le système de commande en ligne en temps réel, lorsque l'utilisateur sélectionne des plats et passe une commande

JavaScript et WebSocket : créer un système efficace de prévisions météorologiques en temps réel JavaScript et WebSocket : créer un système efficace de prévisions météorologiques en temps réel Dec 17, 2023 pm 05:13 PM

JavaScript et WebSocket : Construire un système efficace de prévisions météorologiques en temps réel Introduction : Aujourd'hui, la précision des prévisions météorologiques revêt une grande importance pour la vie quotidienne et la prise de décision. À mesure que la technologie évolue, nous pouvons fournir des prévisions météorologiques plus précises et plus fiables en obtenant des données météorologiques en temps réel. Dans cet article, nous apprendrons comment utiliser la technologie JavaScript et WebSocket pour créer un système efficace de prévisions météorologiques en temps réel. Cet article démontrera le processus de mise en œuvre à travers des exemples de code spécifiques. Nous

Tutoriel JavaScript simple : Comment obtenir le code d'état HTTP Tutoriel JavaScript simple : Comment obtenir le code d'état HTTP Jan 05, 2024 pm 06:08 PM

Tutoriel JavaScript : Comment obtenir le code d'état HTTP, des exemples de code spécifiques sont requis Préface : Dans le développement Web, l'interaction des données avec le serveur est souvent impliquée. Lors de la communication avec le serveur, nous devons souvent obtenir le code d'état HTTP renvoyé pour déterminer si l'opération a réussi et effectuer le traitement correspondant en fonction de différents codes d'état. Cet article vous apprendra comment utiliser JavaScript pour obtenir des codes d'état HTTP et fournira quelques exemples de codes pratiques. Utilisation de XMLHttpRequest

Comment utiliser insertBefore en javascript Comment utiliser insertBefore en javascript Nov 24, 2023 am 11:56 AM

Utilisation : En JavaScript, la méthode insertBefore() est utilisée pour insérer un nouveau nœud dans l'arborescence DOM. Cette méthode nécessite deux paramètres : le nouveau nœud à insérer et le nœud de référence (c'est-à-dire le nœud où le nouveau nœud sera inséré).

Comment obtenir facilement le code d'état HTTP en JavaScript Comment obtenir facilement le code d'état HTTP en JavaScript Jan 05, 2024 pm 01:37 PM

Introduction à la méthode d'obtention du code d'état HTTP en JavaScript : Dans le développement front-end, nous devons souvent gérer l'interaction avec l'interface back-end, et le code d'état HTTP en est une partie très importante. Comprendre et obtenir les codes d'état HTTP nous aide à mieux gérer les données renvoyées par l'interface. Cet article explique comment utiliser JavaScript pour obtenir des codes d'état HTTP et fournit des exemples de code spécifiques. 1. Qu'est-ce que le code d'état HTTP ? Le code d'état HTTP signifie que lorsque le navigateur lance une requête au serveur, le service

See all articles