Maison  >  Article  >  interface Web  >  Une introduction détaillée au regroupement des expressions régulières et des assertions javascript

Une introduction détaillée au regroupement des expressions régulières et des assertions javascript

黄舟
黄舟original
2017-04-24 09:19:491584parcourir

这篇文章主要介绍了 javascript 正则表达式分组、断言详解的相关资料,需要的朋友可以参考下

 javascript 正则表达式分组、断言详解

  提示:阅读本文需要有一定的正则表达式基础。

       正则表达式中的断言,作为高级应用出现,倒不是因为它有多难,而是概念比较抽象,不容易理解而已,今天就让小菜通俗的讲解一下。

       如果不用断言,以往用过的那些表达式,仅仅能获取到有规律的字符串,而不能获取无规律的字符串。

       举个例子,比如html源码中有b2386ffb911b14667cb8f0f91ea547a7xxx6e916e0f7d1e588d4f442bf645aedb2f标签,用以前的知识,我们只能确定源码中的b2386ffb911b14667cb8f0f91ea547a7和6e916e0f7d1e588d4f442bf645aedb2f是固定不变的。因此,如果想获取页面标题(xxx),充其量只能写一个类似于这样的表达式:b2386ffb911b14667cb8f0f91ea547a7.*6e916e0f7d1e588d4f442bf645aedb2f,而这样写匹配出来的是完整的b2386ffb911b14667cb8f0f91ea547a7xxx6e916e0f7d1e588d4f442bf645aedb2f标签,并不是单纯的页面标题xxx。

       想解决以上问题,就要用到断言知识。

       在讲断言之前,读者应该先了解分组,这有助于理解断言。

       分组在正则中用()表示,根据小菜理解,分组的作用有两个:

       n  将某些规律看成是一组,然后进行组级别的重复,可以得到意想不到的效果。

       n  分组之后,可以通过后向引用简化表达式。

        先来看第一个作用,对于IP地址的匹配,简单的可以写为如下形式:

       \d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}

       但仔细观察,我们可以发现一定的规律,可以把.\d{1,3}看成一个整体,也就是把他们看成一组,再把这个组重复3次即可。表达式如下:

       \d{1,3}(.\d{1,3}){3}

       这样一看,就比较简洁了。

再来看第二个作用,就拿匹配b2386ffb911b14667cb8f0f91ea547a7xxx6e916e0f7d1e588d4f442bf645aedb2f标签来说,简单的正则可以这样写:

       <title>.*</title>

       可以看出,上边表达式中有两个title,完全一样,其实可以通过分组简写。表达式如下:

       <(title)>.*</\1>

       这个例子实际上就是反向引用的实际应用。对于分组而言,整个表达式永远算作第0组,在本例中,第0组是cc97656aee6d4c4c5fa65b10b70c0f4c.*c0f8603dd44f0db5dcc943cf687721b3,然后从左到右,依次为分组编号,因此,(title)是第1组。

       用\1这种语法,可以引用某组的文本内容,\1当然就是引用第1组的文本内容了,这样一来,就可以简化正则表达式,只写一次title,把它放在组里,然后在后边引用即可。

       以此为启发,我们可不可以简化刚刚的IP地址正则表达式呢?原来的表达式为\d{1,3}(.\d{1,3}){3},里边的\d{1,3}重复了两次,如果利用后向引用简化,表达式如下:

       (\d{1,3})(.\1){3}

       简单的解释下,把\d{1,3}放在一组里,表示为(\d{1,3}),它是第1组,(.\1)是第2组,在第2组里通过\1语法,后向引用了第1组的文本内容。

       经过实际测试,会发现这样写是错误的,为什么呢?

       小菜一直在强调,后向引用,引用的仅仅是文本内容,而不是正则表达式!

       也就是说,组中的内容一旦匹配成功,后向引用,引用的就是匹配成功后的内容,引用的是结果,而不是表达式。

       因此,(\d{1,3})(.\1){3}这个表达式实际上匹配的是四个数都相同的IP地址,比如:123.123.123.123。

       至此,读者已经掌握了传说中的后向引用,就这么简单。

       接下来说说什么是断言。

La soi-disant assertion consiste à indiquer qu'une chaîne qui satisfait un certain modèle apparaîtra avant ou après une certaine chaîne.

Prenons l'exemple de l'ouverture de l'article Ce que nous voulons, c'est xxx Il n'y a pas de règles, mais il y aura certainement b2386ffb911b14667cb8f0f91ea547a7 049d4210849359bc9c69982d873833a0, ça suffit.

Si vous souhaitez préciser que b2386ffb911b14667cb8f0f91ea547a7 apparaîtra définitivement avant de spécifier xxx, utilisez l'assertion suivie de l'expression : (?<=b2386ffb911b14667cb8f0f91ea547a7).*

Après spécifiant xxx 6e916e0f7d1e588d4f442bf645aedb2f apparaîtra certainement, utilisez simplement le prédicat positif, expression : .*(?=6e916e0f7d1e588d4f442bf645aedb2f)

        Ajoutez les deux ensemble, c'est (?<=

Cela correspondra à xxx.

Je pense que les lecteurs sont déjà confus après avoir vu cela, alors ne vous inquiétez pas, attendons que les plats d'accompagnement soient expliqués lentement.

En fait, c'est très simple une fois que l'on maîtrise les règles. Qu'il soit envoyé en premier ou plus tard, c'est par rapport à xxx, c'est-à-dire par rapport à la chaîne cible.

S'il y a une condition après la chaîne cible, on peut comprendre que la chaîne cible est devant, utilisez donc une assertion d'anticipation et placez-la après la chaîne cible.

S'il y a une condition devant la chaîne cible, on peut comprendre que la chaîne cible vient après, utilisez une post-assertion et placez-la avant la chaîne cible.

Si une condition spécifiée est remplie, elle est positive.

Si une condition spécifiée n'est pas remplie, elle sera négative.

Les assertions ne sont que des conditions pour vous aider à trouver la corde dont vous avez réellement besoin. Elles ne se correspondront pas toutes seules !

(?=X )

零宽度正先行断言。仅当子表达式 X 在 此位置的右侧匹配时才继续匹配。例如,/w+(?=/d) 与后跟数字的单词匹配,而不与该数字匹配。此构造不会回溯。

(?!X)

零宽度负先行断言。仅当子表达式 X 不在 此位置的右侧匹配时才继续匹配。例如,例如,/w+(?!/d) 与后不跟数字的单词匹配,而不与该数字匹配 。

(?<=X)

零宽度正后发断言。仅当子表达式 X 在 此位置的左侧匹配时才继续匹配。例如,(?<=19)99 与跟在 19 后面的 99 的实例匹配。此构造不会回溯。

(?

零宽度负后发断言。仅当子表达式 X 不在此位置的左侧匹配时才继续匹配。例如,(?

(?=X )

zéro La largeur est affirmée par anticipation. La correspondance continue uniquement si la sous-expression X correspond à droite de cette position. Par exemple, /w+(?=/d) correspond à un mot suivi d'un nombre, mais pas au nombre. Cette construction ne revient pas en arrière.
(?!X) Assertion d'anticipation négative de largeur nulle. Continuez la correspondance uniquement si la sous-expression X ne correspond pas à droite de cette position. Par exemple, /w+(?!/d) correspond à un mot qui n'est pas suivi d'un chiffre, mais pas du chiffre.
(?<=X) Assertion de publication positive de largeur nulle. La correspondance continue uniquement si la sous-expression X correspond à la gauche de cette position. Par exemple, (?<=19)99 correspond aux instances de 99 qui suivent 19. Cette construction ne revient pas en arrière.
(? Assertion de publication négative de largeur nulle. Continuez la correspondance uniquement si la sous-expression X ne correspond pas à la gauche de cette position. Par exemple, (?
Cela peut être vu à partir de la forme d'expression de l'assertion Out, il utilise la notation de regroupement, mais un point d'interrogation est ajouté au début. Ce point d'interrogation signifie qu'il s'agit d'un groupe non capturant. Ce groupe n'a pas de numéro et ne peut pas être utilisé pour des références arrière. être utilisé comme une assertion.

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:
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