Home  >  Article  >  Web Front-end  >  A detailed introduction to the grouping of javascript regular expressions and assertions

A detailed introduction to the grouping of javascript regular expressions and assertions

黄舟
黄舟Original
2017-04-24 09:19:491544browse

这篇文章主要介绍了 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。

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

       接下来说说什么是断言。

The so-called assertion is to indicate that a string that satisfies a certain pattern will appear before or after a certain string.

Take the example of the articleopening as an example. What we want is xxx. It has no rules, but it will definitely have b2386ffb911b14667cb8f0f91ea547a7 in front of it and 654dd6e53a17d10cb0054dff54c7d997, that's enough.

& will definitely appear before you specify xxx. 6e916e0f7d1e588d4f442bf645aedb2f will definitely appear, just use the positive first assertion, the expression: .*(?=6e916e0f7d1e588d4f442bf645aedb2f)

                    Add the two together, it is (?<=

This will match xxx.

I believe readers are already confused after seeing this, so don’t worry, let’s wait for the side dishes to be explained slowly.

In fact, it is very simple once you master the rules. Whether it is sent first or later, it is relative to xxx, that is, relative to the target string.

         

If there is a condition after the target string, it can be understood that the target string is in front, so use the look-ahead assertion and place it after the target string.

If there is a condition in front of the target string, it can be understood that the target string comes after it, so use a post-assertion and place it before the target string.

If a certain condition is met, it is positive.

If a certain condition is not met, it will be negative.

Assertions are just conditions to help you find the string you really need. They will not match themselves!

(?=X )Zero-width positive lookahead assertion. Matching continues only if subexpression X matches to the right of this position. For example, /w+(?=/d) matches a word followed by a number, but not the number. This construction does not backtrack. (?!X)Zero-width negative lookahead assertion. Continue matching only if subexpression X does not match to the right of this position. For example, /w+(?!/d) matches a word that is not followed by a number, but not the number. (?<=X) Zero-width positive assertion. Matching continues only if subexpression X matches to the left of this position. For example, (?<=19)99 matches instances of 99 that follow 19. This construction does not backtrack. (?

Zero-width negative post assertion. Continue matching only if subexpression X does not match to the left of this position. For example, (?

It can be seen from the expression form of the assertion that it uses is the grouping symbol, but a question mark is added at the beginning. This question mark means that this is a non-capturing group. This group has no number and cannot be used for backward references. It can only be used as an assertion.

The above is the detailed content of A detailed introduction to the grouping of javascript regular expressions and assertions. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn