javascript - What is the difference between ?= and ?: in regular expressions?
天蓬老师
天蓬老师 2017-06-15 09:22:42
0
5
1102

Just follow the example: add commas between every three numbers

"123456789".replace(/(\d{3})(?:[^$])/g, ",");
//"123,567,9"

"123456789".replace(/(\d{3})(?=[^$])/g, ",");
//"123,456,789"

Another example that appeared in the previous forum is to add commas between every three numbers

先看看 (?=pattern) 的使用,下面这个是正确的:

function groupByCommas(n) {
  return n.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
console.log(groupByCommas(1234567));    //1,234,567

如果我们把 ?= 换成 ?: 的话:

function groupByCommas(n) {
  return n.toString().replace(/\B(?:(\d{3})+(?!\d))/g, ",");
}
console.log(groupByCommas(1234567));    //1,

Needless to say the concepts of the two, I found an answer saying: The difference is that ?= is a positive positive assertion, and the matching does not account for the length of the query; while ?: is a non-acquisition match, and the matching is Occupies the query length.

But I still don’t quite understand the statement that the query occupies the length here. Explain it to the example. Does it mean that the first example (?=[^$]) matches non-ending, so the length of the non-ending after 123 is the smallest. It is 1 character, so 4 is replaced together? Then why not just replace it directly to the end? The second example (?=(\d{3}) (?!\d)) matches 3 or a multiple of 3, and matches directly to the end, so 234567 is also directly replaced? So my understanding is definitely wrong

I don’t understand it very thoroughly. I welcome you to answer my confusion with examples. Thank you very much!

天蓬老师
天蓬老师

欢迎选择我的课程,让我们一起见证您的进步~~

reply all(5)
刘奇
  1. "123456789".replace(/(d{3})(?:[^$])/g, "$1,");
    () represents capturing brackets, (?:) Represents non-capturing brackets, so the content matched by the first bracket will be placed in $1, and the content matched by the second bracket will not be placed in $2. d{3} means three consecutive numbers, [^$] means matches one character, as long as this character is not the $ symbol . It should be noted that [] means matching any character in it, but definitely There must be one, so the length of the character matched by [] must be 1, and there is no case of 0. In addition, the $ symbol in [$] has no special meaning, it is the character $, and Does not match the end of the string.
    Because d{3} matches three characters, [^$] matches one character, so this regular match matches 4 characters; looking at the matching process, first "1234" is satisfied, and "123" matches d {3}, "4" matches [^$], at this time $1="123", so "1234" is replaced by "123,". Then start the next matching from 5, similar "5678" meets the condition, $1="567", so "5678" is replaced with "567,". Then the matching starts from 9. There is no matching below. The matching ends and the result is "123,567,9".

  2. "1234567".replace(/B(?:(d{3})+(?!d))/g, ",");
    B matches non-word boundaries, which is also a position, no Width, (d{3})+ matches a sequence of numbers that are multiples of 3, and the number is at least 3. + is a quantifier, indicating 1 to multiple times. The default is greedy. Greedy means matching as many as possible , (?!d) means that this position is not followed by a number.
    Look at the example. First, B does not match the beginning of the line, so the matching position is moved to the position after "1". At this time, B matches the position after 1, and then "234" and "567" match d{3} , because it is a greedy match, so (d{3})+ matches "234567", and because 7 is the end of the string, it satisfies the assertion that (?!d) is not a number, so the entire regular matching result is "234567", so "234567" was replaced by ",". 1 does not move, so "1234567" becomes "1,".

  3. "123456789".replace(/(d{3})(?=[^$])/g, "$1,");
    This regular expression does not meet the requirement of "add comma at thousandth place" , "123456789" is just a special case (the number of digits is exactly a multiple of 3), if replaced with "12345678" the result is "123,456,78".

typecho

Occupied or "consumed" means whether the matched part can be matched by other regular expressions (later assertions, or the next time of / /g). If it is "consumed", it can no longer be matched.

"123456789".replace(/(\d{3})(?=[^$])/g, (m, ) => `{matched=${m} =${}}`);
// => '{matched=123 =123}{matched=456 =456}789'
// (?=) 第一次没有消耗掉4, 第二次会从456..开始

"123456789".replace(/(\d{3})(?:[^$])/g, (m, ) => `{matched=${m} =${}}`);
// => '{matched=1234 =123}{matched=5678 =567}9'
// (?:) 第一次消耗掉4,第二次会从567..开始

Another example 1 [^$] matches a non-$ character, regardless of the end of the line.

巴扎黑

(?=456) matches a position followed by 456.
For example, 123 (?=456) will match 123 in 123456, but will not match 123 in 123457. Not occupied means that it will match the 456 after 123 and will not be occupied.
123456 matches 123456, and 123(?=456)456 also matches 123456 with (?=456) added at the end, which is actually meaningless.

You can use parentheses to change the priority, etc. in regular expressions. In addition, for the parenthesized part, a number will be assigned incrementally from left to right. You can use the number to reference the text matched by this part later. In JS replace, the replacement part can be used to reference the match of this part like $1.
For example, (a)1 will match two consecutive a’s, ([A-Z])1 will match two consecutive letters of the same size, (A-Z)1([a-z])2 will match two consecutive letters Upper and lower letters, followed by two consecutive lowercase letters (uppercase and lowercase letters can be different).

Sometimes, we just want to change the priority and don’t want to assign a number (rarely used), just use (?:)
For example, (a)(?:b)(c)12 matches abcac, But (a)(b)(c)12 matches abcab.

http://zonxin.github.io/post/...

世界只因有你

Enclosed with () can be matched using $1 (to $9)

As shown below, you can use $1 to match (capture) the matched values ​​

, in parentheses.

a = '123,456';
a.match(/\d{3}(,)/)
Use

(?:) to not capture this one. It’s just that you can’t get the value obtained by the brackets through $1

a.match(/\d{3}(?:,)/)
The above two match values ​​containing

, Look at the following one,
(?=) is used for matching, but it does not appear in the result. The result below is not ,

a.match(/\d{3}(?=,)/)
The results of the three codes are as shown in the figure

This way of writing is very useful. There are some contents that you don’t want to appear in the results, but if you don’t use it and the matching is incomplete, you can use this

世界只因有你

These two functions are completely unrelated
Mode 1pattern1(?=pattern2)Forward positive assertion; Mode 2(?:pattern3)Non-capturing grouping

1.Pattern 1: pattern2 itself does not participate in the matching. It asserts the matching result of pattern1 (ret1): Does the content after ret1 in the string match pattern2? If yes, then ret1 is the matching result of Pattern 1, if not, then ret1 is not the matching result of Pattern 1. Of course, if pattern1 is not matched, pattern 1 will also not be matched.

Example:

  var str1='abc',str2='acb';var reg=/a(?=b)/
  console.log(reg.test(str1),reg.test(str2)) //=>true false
  //因为reg.test(str1)为真,输出匹配结果
  console.log(str1.match(reg)[0])  //=>a
2.

Mode 2 is mainly used to distinguish capturing grouping(pattern4), recorded as Mode 3

In mathematics, parentheses are used to perform a priority operation; and

Mode 3, in addition to isolating the code, pattern4 participates in the matching, and the matching results of pattern4 are stored

For the non-capturing grouping of

pattern 2(?:pattern3), it means that the result of pattern3 will not be stored, but pattern3 itself participates in the matching and is mainly used to isolate the code. That is to express the original meaning of
(), and () has the definition of capturing grouping in the regular expression, so a
?: is added to show the difference. This has the same effect as the escape character .

Example

var  str='abc'
var  reg1=/(\w)(\w)(\w)/
var  reg2=/(\w)(?:\w)(\w)/
//捕获了3次,RegExp.,RegExp.,RegExp....依次存储捕获结果
var ret1=str.match(reg1)
console.log(RegExp.,RegExp.,RegExp.)//=>a b c
var ret2=str.match(reg2)
//捕获了2次
console.log(RegExp.,RegExp.) //=>a c
@luckness gave a detailed answer to the question's content, and I answered the question's title.

Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template