>  기사  >  웹 프론트엔드  >  정규식에서 lastIndex 사용에 대한 자세한 설명

정규식에서 lastIndex 사용에 대한 자세한 설명

php中世界最好的语言
php中世界最好的语言원래의
2018-03-29 16:20:122010검색

이번에는 정규 표현식에서 lastIndex를 사용하는 방법에 대해 자세히 설명하겠습니다. lastIndex를 정규 표현식에서 사용할 때 주의사항은 무엇인가요? 실제 사례를 살펴보겠습니다.

다음 출력 내용을 순서대로 작성하세요.

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

stringabcabc에 문자 a가 있는지 확인하는 매우 간단한 정규식테스트입니다. 그런데 그 결과에는 특별한 허위가 있습니다. 왜일까요?

lastIndex(매개변수 g가 있는 정규식의 경우)

모든 인스턴스화된 RegExp 개체에는 초기 값이 0인 lastIndex 속성이 있습니다.

/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

그리고 이 lastIndex는 이 정규 규칙을 사용하여 다른 일치 작업을 수행할 때 일치의 시작 위치입니다. 일치에 실패하면 lastIndex가 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

이것을 보고 궁금증은 해결됐고, 다음 단계는 확장입니다.

재선언되지 않은 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

분명히 lastIndex로 인해 판단에 오류가 있습니다. 여기서 매개변수 g 없이 reg를 수정하거나 reg를 다시 선언할 수 있습니다. 물론 첫 번째 일치 후 reg.lastIndex = 0을 수동으로 수정할 수도 있습니다.

사전 확인

그럼 사전 확인에 대해 이야기해 보겠습니다. 사전 확인은 말 그대로 일치하는 쿼리를 준비하는 것, 즉 일치하는 콘텐츠의 다음 콘텐츠를 쿼리하는 것을 의미하지만 일치하는 쿼리만 준비하여 돌아오지 않습니다.

종종 문자열에서 특정 문자와 특정 문자를 일치시켜야 하지만 일치 결과에 다음 문자를 포함할 필요는 없습니다. 예:

아래 문자열에서 뒤에 2가 오는 모든 문자를 찾으세요. .

var str = 'a1b2c22d31e4fg6h2';
'a1b2c22d31e4fg6h2'.match(/[a-z]2/g); // ["b2", "c2", "h2"]

이렇게 하면 2가 포함된 문자열이 일치할 수 있지만 숫자 2는 필요하지 않고 여기에는 문자만 필요합니다. 사전 확인:

'a1b2c22d31e4fg6h2'.match(/[a-z](?=2)/g); // ["b", "c", "h"]

을 사용하면 조건이 완전히 충족되었음을 알 수 있는데, 사전 확인이 이 글의 주제인 lastIndex와 얼마나 연관이 있을까요?

test를 사용하는 이유를 여기서 설명해야 합니다. Match가 실패할 때까지 모든 것을 일치시킵니다. lastIndex는 0으로 재설정됩니다.

첫 번째 일치가 성공하거나 일치가 실패하면 Exec 및 test가 반환되며 더 이상 일치하지 않습니다.

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

문제가 보이시나요? 사전 확인된 lastIndex에는 사전 확인된 내용이 포함되어 있지 않습니다! 이는 많은 판단을 단순화하는 데 사용될 수 있습니다.

예를 들어 비밀번호를 일치시키려면 대문자 1개, 소문자 1개, 숫자 1개 이상이 포함되어야 하며 길이는 6자 이상이어야 하며 숫자와 문자의 조합만 가능합니다.

사전 확인 없이 상황에 따라 다음과 같이 판단합니다:

/[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)

분해해서 확인:

(?=.*[a-z]) 소문자는 있지만 사전 확인 일치가 실패하고 false를 반환합니다. 성공 lastIndex는 변경되지 않으며 여전히 0입니다. 같은 방식으로 우리는 두 외부 소스의 사전 확인 내용을 이해합니다. 마지막 것은 6보다 큰 영숫자 조합의 일치입니다. 그러나 이전 항목은 사전 확인이며 lastIndex는 항상 0이 아닙니다. 각 일치 항목은 처음부터 일치하므로 요구 사항이 충족됩니다.

이 기사의 사례를 읽은 후 방법을 마스터했다고 생각합니다. 더 흥미로운 정보를 보려면 PHP 중국어 웹사이트의 다른 관련 기사를 주목하세요!

추천 자료:

일반 여러 줄 모드와 단일 줄 모드 사용에 대한 자세한 그래픽 설명

PHP를 기반으로 한 일반 너비가 0인 어설션 사용에 대한 자세한 설명

위 내용은 정규식에서 lastIndex 사용에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.