Home  >  Article  >  Web Front-end  >  Detailed explanation of the use of lastIndex in regular expressions

Detailed explanation of the use of lastIndex in regular expressions

php中世界最好的语言
php中世界最好的语言Original
2018-03-29 16:20:122070browse

This time I will bring you a detailed explanation of the use of lastIndex in regular expressions. What are the precautions for using lastIndex in regular expressions? The following is a practical case, let's take a look.

Write the following output content in sequence.

var reg1 = /a/;
var reg2 = /a/g;
console.log(reg1.test('abcabc')); // true
console.log(reg1.test('abcabc')); // true
console.log(reg1.test('abcabc')); // true
console.log(reg1.test('abcabc')); // true
console.log(reg2.test('abcabc')); // true
console.log(reg2.test('abcabc')); // true
console.log(reg2.test('abcabc')); // false
console.log(reg2.test('abcabc')); // true
A very simple

regular expressiontest to find whether there is a character a in the stringabcabc. But there is a special false in the result. Why?

lastIndex (for regular expression with parameter g)

In each instantiated

RegExp object , there is a lastIndex attribute whose initial value is 0.

/a/.lastIndex // 0
new RegExp('a').lastIndex // 0
lastIndex表示匹配成功时候,匹配内容最后一个字符所在原字符串中的位置 + 1,也就是匹配内容的下一个字符的index(如果匹配内容在字符串的结尾,同样返回原字符串中的位置 + 1,也就是字符串的length)。如果未带参数g,lastIndex始终为0。
var reg = /ab/g;
reg.test('123abc');
console.log(reg.lastIndex) // 5
// 匹配内容在最后
var reg = /ab/g;
reg.test('123ab');
console.log(reg.lastIndex) // 5
// 不带参数g
var reg = /ab/;
reg.test('123abc');
console.log(reg.lastIndex) // 0
And this lastIndex is the starting position of matching when using this regular expression for other matching operations. When the match fails, lastIndex is reset to 0.

var reg = /ab/g;
// 初始值为0,从最开始匹配 匹配成功, lastIndex为4
console.log(reg.test('12ab34ab'), reg.lastIndex); // true 4
// 从第4位字符"3"开始匹配 匹配内容为第二个ab lastIndex 为 8
console.log(reg.test('12ab34ab'), reg.lastIndex); // true 8
// 从第8位 (字符长度为8,没有第8位) 开始匹配 匹配不成功 重置lastIndex 为 0
console.log(reg.test('12ab34ab'), reg.lastIndex); // false 0
// 从头匹配 同第一步
console.log(reg.test('12ab34ab'), reg.lastIndex); // true 4
After seeing this, the question has been answered, and the next step is to expand.

It is easy to make mistakes with unredeclared reg.

// 测试字符串str1 和 str2 是否都含有ab字符
var reg = /ab/g;
var str1 = '123ab';
var str2 = 'ab123';
console.log(reg.test(str1)); // true
console.log(reg.test(str2)); // false
Obviously there is an error in judgment due to lastIndex. Here you can modify reg without parameter g or re-declare reg. Of course, you can also manually modify reg.lastIndex = 0 after the first match.

Pre-check

Then let’s talk about pre-check, which literally means to prepare the matching query, that is, to query the next content of the matching content, but only The prepared query matches and does not return.

Often we need to match certain characters in a string followed by certain characters, but we do not need to include the following characters in the matching result, for example:

Find out the following characters in the string Characters are followed by all characters of 2.

var str = 'a1b2c22d31e4fg6h2';
'a1b2c22d31e4fg6h2'.match(/[a-z]2/g); // ["b2", "c2", "h2"]
In this way, although the string with 2 can be matched, we do not need the number 2, only the characters are needed here. By using the pre-check:

'a1b2c22d31e4fg6h2'.match(/[a-z](?=2)/g); // ["b", "c", "h"]
, you can see that the conditions are completely met, but how much does the pre-check have to do with lastIndex, the subject of this article?

Let’s use test to see. As for why we use test, we need to explain here. Match matches everything until the match is unsuccessful. When the match is unsuccessful, the lastIndex is reset to 0. .

Exec and test will return if the first match is successful or if the match fails, and will not continue to match.

var reg1 = /[a-z](?=2)/g;
var reg2 = /[a-z]2/g;
var str = 'a1b2c22d31e4fg6h2';
console.log(reg1.test(str), reg1.lastIndex); // true 3
console.log(reg1.test(str), reg1.lastIndex); // true 5
console.log(reg1.test(str), reg1.lastIndex); // true 16
console.log(reg1.test(str), reg1.lastIndex); // false 0
console.log(reg2.test(str), reg2.lastIndex); // true 4
console.log(reg2.test(str), reg2.lastIndex); // true 6
console.log(reg2.test(str), reg2.lastIndex); // true 17
console.log(reg2.test(str), reg2.lastIndex); // false 0
Do you see the problem? The pre-checked lastIndex does not contain the pre-checked content! This can be used to simplify many judgments.

For example, if we want to match the password, it must have at least one uppercase letter, one lowercase letter, and one number, and it must be at least 6 characters long and can only be a combination of numbers and letters.

According to the situation without pre-checking, it will be judged like this:

/[a-z]/.test(pwd) && /[A-Z]/.test(pwd) && /\d/.test(pwd) && /^[a-zA-Z0-9]{6,}$/.test(pwd);
But:

/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[a-zA-Z0-9]{6,}$/.test(pwd)
Breaked it out:

(?=.*[ a-z]) Whether there are lowercase letters but the pre-check match fails and returns false. If the lastIndex is successful, it does not change and is still 0. In the same way, we understand the pre-check content of the two external sources. The last one is to match the combination of letters and numbers above 6, but the previous ones are all pre-checks. , lastIndex is always not 0, and each match is matched from the beginning, so the requirements are met.

I believe you have mastered the method after reading the case in this article. For more exciting information, please pay attention to other related articles on the php Chinese website!

Recommended reading:

Detailed graphic explanation of using regular multi-line mode and single-line mode

Based on PHP regular zero-width Detailed explanation of the use of assertions

The above is the detailed content of Detailed explanation of the use of lastIndex in regular expressions. 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