머리말
최근에 나는 일부 장소에서 JavaScript의 규칙 성의 성능이 다른 언어 나 도구의 성능과 다소 다르며 비교적 대안이라는 것을 알았습니다. 당신이 그것들을 쓰는 것은 거의 불가능하지만 아래에서 언급 한 규칙을 거의 사용하지 못하지만 결국 이해하는 것이 좋습니다.
이 기사의 코드 예제는 ES5와 호환되는 JavaScript 환경에서 실행됩니다. 즉, IE9 이전 버전의 성능, FX4 주변 버전 등은 아래에 언급 한 것과 다를 수 있습니다.
1. 빈 캐릭터 클래스
[] 포함하지 않는 문자 클래스를 빈 empty char class 클래스라고합니다. 다른 언어에서는이 글쓰기 방법이 불법이며 모든 문서와 튜토리얼은 불법 구문에 대해 이야기하지 않기 때문에 다른 사람들이 전화를 본 적이 없다고 생각합니다. 다른 언어 나 도구 가이 오류를보고하는 방법을 보여 드리겠습니다.
$ echo | grep '[]'grep : 타의 추종을 불허 [또는 [^$ echo | sed '/[]/'sed : -e expression #1, 캐릭터 4 : 말라 내지 않은 주소 정규 표현식 $ echo | awk '/[]/'awk : cmd. 줄 : 1 : /[] /awk : cmd. 라인 : 1 : ^ 종결되지 않은 regexpawk : cmd. 줄 : 1 : 오류 : 타의 추종을 불허 [또는 [^:/[] // $ echo | perl -ne '/[]/'비교할 수없는 [Regex에서; <- 여기 m/ [<-here]/ at -e line 1에 표시됩니다. $ echo | Ruby -ne '/[]/'-e : 1 : 빈 숯 클래스 :/[]/$ python -c 'import re; re.match ( "[]", ",")'traceback (가장 최근 호출) : 파일 "<string>", <module> 파일 "e : /python/lib/re.py", line 137, line 137, _ _ _ _ _ _ _ _ _ _ line 137, _ _ _ _ _ _ pattern (fater) "e : /python/lib/re.py", 244 행, _compile rain error, v # invalid expressionsre_constants.error : 예상치 못한 정규 표현식의 끝
JavaScript에서는 빈 문자 클래스는 법적 정규 구성 요소이지만 그 효과는 "결코 일치하지 않습니다", 즉 모든 것이 실패합니다. 그것은 (empty negative lookahead)(?!) 의 효과와 동일합니다.
js> "뭐든지/n".match (/[]/g) // null 문자 클래스, nulljs> "뭐든지"
분명히, 이런 종류의 것은 JavaScript에서 쓸모가 없습니다.
2. 빈 캐릭터 클래스를 무효화하십시오
문자를 포함하지 않는 음수 문자 클래스를 음수 빈 숯 클래스 또는 빈 음성 숯 클래스라고합니다.이 명사는 "자체 제작"되었고 위에서 언급 한 빈 문자 클래스와 유사하기 때문입니다. 이 글쓰기 방법은 다른 언어에서도 불법입니다.
$ echo | grep '[^]'grep : 타의 추종을 불허 [또는 [^$ echo | sed '/[^]/'sed : -e expression #1, 문자 5 : 말라 내지 않은 주소 정규 표현식 $ echo | awk '/[^]/'awk : cmd. 줄 : 1 : /[^] /awk : cmd. 라인 : 1 : ^ 종결되지 않은 regexpawk : cmd. 줄 : 1 : 오류 : 타의 추종을 불허 [또는 [^:/[^] // $ echo | perl -ne '/[^]/'타의 추종을 불허하는 [Regex에서; <- 여기 m/ [<-here ^]/ at -e line 1에 표시됩니다. $ echo | Ruby -ne '/[^]/' -e : 1 : 빈 char -class :/[^]/$ python -c 'import re; re.match ( "[^]", ")'traceback (가장 최근 호출) : 파일"<string> ", <module> file"e : /python/lib/re.py ", line 137, line 137, line 137, in matchile (patter) "e : /python/lib/re.py", 244 행, _compile Rain Error, v # invalid expressionsre_constants.error : 예상치 못한 정규 표현식 $
JavaScript에서는 널 문자 클래스를 부정하는 것이 합법적 인 일반 구성 요소입니다. 그 효과는 널 캐릭터 클래스의 효과와 반대입니다. Newline "/n" 포함하여 모든 문자와 일치 할 수 있습니다. 즉, 공통 [/s/S] 및 [/w/W] 와 동일합니다.
JS> "뭐든지".match (/[^]/g) // neizontal 문자 클래스, 모든 문자 [ "w", "h", "a", "t", "e", "v", "e", "r", "/n"] js> "뭐든지".match (/[/s/s]/g) // 보완 문자 클래스에 일치합니다. "t", "e", "v", "e", "r", "/n"]]]
캐릭터 클래스에 일치 할 캐릭터가 있어야하기 때문에 "영구 일치 규칙 성"이라고 할 수는 없습니다. 대상 문자열이 비어 있거나 왼쪽 규칙에 의해 소비 된 경우, 예를 들어 일치가 실패합니다.
js> /abc;^ ]/.test("ABC ") // C 이후 문자가없고 일치하는 것은 실패했습니다.진정한 "영구 일치하는 규칙"을 알고 싶다면 이전에 번역 한 기사를 확인할 수 있습니다. "빈"규칙
3. []] 및 [^]]
이것은 비교적 간단합니다. 즉, Perl의 정규 표현식과 다른 Linux 명령에서, 캐릭터 클래스 [] 에 왼쪽 사각형 브래킷 바로 다음 오른쪽 []] 브래킷이 포함 된 경우 오른쪽 사각형 브래킷은 일반 문자로 간주됩니다. JavaScript에서는이 규칙 성은 빈 문자 클래스와 오른쪽 정사각형 브래킷으로 인식되며 빈 캐릭터 클래스는 아무 것도 일치하지 않습니다 .[^]] 에서 비슷합니다 : JavaScript에서, 그것은 임의의 문자 (Negative null 문자 클래스)와 "a]","b]" 와 같은 오른쪽 정사각형 괄호와 일치하지만 다른 언어에서는 비 아닌 문자와 일치합니다.
$ perl -e 'print "]"= ~/[]]/'1 $ js -e 'print (/[]]/. test ( "]"))'false $ perl -e 'print "x"= ~/[^]]/'1 $ js -e 'print (/[^]]/. test ( "x"))'거짓
4. $ 앵커 포인트
일부 초보자들은 $가 Newline 캐릭터 "/n" 과 일치한다고 생각합니다. 이것은 큰 실수입니다. $는 0 폭의 어설 션이며 실제 캐릭터와 일치하는 것은 불가능하며 한 위치에만 일치 할 수 있습니다. 내가 말하고 싶은 차이점은 다중선이 아닌 모드에서 발생합니다. 당신은 비 영화선 모드에서 $ $가 마지막 캐릭터 이후에 위치와 일치하지 않는다고 생각할 수 있습니까? 사실 그렇게 간단하지 않습니다. 대부분의 다른 언어에서, 대상 문자열의 마지막 문자가 Newline 문자 "/n" 인 경우, $는 Newline 이전의 위치와 일치합니다. 많은 언어에는 두 가지 표기법 /z와 /z가 있습니다. 그들 사이의 차이를 알고 있다면, 다른 언어 (Perl, Python, Php, Java, C#...)에서, 비 다중선 모드의 $ $는 /z와 동일하지만 JavaScript에서는 javaScript에서 $가 /z와 동일하다는 것을 이해해야합니다 (마지막 문자가 새로운 라인인지 여부에 관계없이 마지막 위치와 일치합니다). 루비는 기본값이 멀티 라인 모드로 변하기 때문에 특별한 경우입니다. 다중선 모드의 $는 각 Newline 이전의 위치와 일치하며 물론 끝에 나타날 수있는 라인 브레이크도 포함됩니다. Yu Sheng의 저서 "정기 가이드 라인"도이 점에 대해 이야기합니다.
$ perl -e 'print "whatly/n"= ~ s/$/clopated charac
5. Dot Metacharacter "."
JavaScript의 정기적 인 표현에서 Dot Metacharacter "." 4 개의 라인 터미네이터 ( /r-carriage return, /n-line newline, /u2028- 라인 분리기, /u2029-paragraph 분리기)를 제외한 모든 문자와 일치 할 수 있지만, 다른 공통 언어에서는 라인 Newline /n 만 제외됩니다.
6. 견적
우리는 모두 일반 캡처 그룹에서 일치하는 문자열에 대한 BackSlash + 숫자 참조에 대한 백 슬래시 + 숫자 참조가 있다는 것을 알고 있습니다. 목적은 다시 일치하거나 대체 결과 (/ $ $)로 일치하는 것입니다. 그러나 참조 된 캡처 그룹이 시작되지 않은 경우 (왼쪽 브래킷이 제한되어 있음) 백색 참조를 사용한다는 특별한 경우가 있습니다. 어떻게됩니까? 예를 들어, 일반 /(/2(a)){2}/ , (a)는 두 번째 캡처 그룹이지만 일치하는 결과는 왼쪽에서 사용됩니다. 우리는 정규 경기가 왼쪽에서 오른쪽으로 일치한다는 것을 알고 있습니다. 이것은이 섹션에서 제목 포워드 참조의 기원입니다. 엄격한 개념이 아닙니다. 이제 당신은 그것에 대해 생각합니다. 다음 JavaScript 코드는 다음과 같습니다.
js>/(/2 (a)) {2}/. exec ( "aaa") ???이 질문에 대답하기 전에 다른 언어의 공연을 살펴 보겠습니다. 마찬가지로 다른 언어에서는이 방법을 쓰는 것이 기본적으로 유효하지 않습니다.
$ echo aaa | grep '(/2 (a)) {2}'grep : invalid back reference $ echo aaa | sed -r '/(/2 (a)) {2}/'sed : -e expression #1, 문자 12 : 불법적 인 백 참조 $ echo aaa | awk '/(/2 (a)) {2}/'$ echo aaa | perl -ne 'print/(/2 (a)) {2}/'$ echo aaa | Ruby -ne 'print $ _ = ~/(/2 (a)) {2}/'$ python -c 'import re; print re.match ( "(/2 (a)) {2}", "aaa")'없음AWK 가이 역전을 지원하지 않기 때문에 AWK에는 오류가 없습니다. /2는 ASCII 코드 2가있는 문자로 해석되지만 Perl Ruby Python에는 오류가 없습니다. 이 디자인이 Perl에 의해 왜 배워야하는지 모르겠지만 효과는 동일합니다. 이 경우 성공적으로 일치하는 것은 불가능합니다.
JavaScript에서는 오류를보고 할뿐만 아니라 성공적으로 일치 할 수도 있습니다. 대답이 방금 생각한 것과 동일하다는 것을 봅시다.
js> /(/2(a) {2 }/.exec("aaa")), "a", "a"] exec 방법에 의해 결과가 반환되는 것을 잊지 못하게하려면 말씀 드리겠습니다. 첫 번째 요소는 완전한 매칭 문자열, 즉 RegExp["$&"] , 각 캡처 그룹 일치, 즉 RegExp.$1 및 RegExp.$2. 일치하는 것이 성공할 수있는 이유는 무엇입니까? 일치하는 프로세스는 무엇입니까? 내 이해는 다음과 같습니다.
먼저, 첫 번째 캡처 그룹 (왼쪽 왼쪽 브래킷)에 들어갑니다. 여기서 첫 번째 유효한 경기는 / RegExp.$2 의 가치는 여전히 undefined 으므로 /2는 대상 문자열의 첫 번째 A 왼쪽에있는 빈 문자와 일치합니다. 요점은 경기가 성공적이라는 것입니다. 계속해서 가서 두 번째 캡처 그룹 (a)는 대상 문자열의 첫 번째 A와 일치하고 RegExp.$2 의 값도 "A"에 할당 된 다음 첫 번째 캡처 그룹이 끝나고 (가장 오른쪽 가장 오른쪽 가장 오른쪽 왼쪽 브래킷) RegExp.$1 의 값도 "A"입니다. 그런 다음 Quantifier {2}, 즉 대상 문자열의 첫 A 후에 정기적 인 새로운 라운드 (/2(a)) 시작됩니다. 핵심 요점은 다음과 같습니다. RegExp.$2 의 값은 /2의 값이 일치하거나 "a"의 첫 번째 라운드의 끝에서 지정된 값이라는 것입니다. 대답은 "아니오", RegExp.$1 및 RegExp.$2 의 값은 정의 undefined 것으로 지워지고 /1 및 /2는 처음과 동일하며 빈 캐릭터와 성공적으로 일치합니다 (작성되었는지 여부에 관계없이 효과가 없음). 대상 문자열의 두 번째 A는 성공적으로 일치하고 RegExp.$1 및 RegExp.$2 의 값은 "A"가되면 RegExp["$&"] 의 값은 완전한 일치 문자열, 첫 두 a : "aa"가됩니다.
이전 버전의 Firefox (3.6)에서, 정량화 자의 재 활성화는 기존 캡처 그룹의 값을 지우지 않으므로, 두 번째 라운드에서 /2는 두 번째 A와 일치 할 것이다.
js> /(/2(a) {2 }/.exec("aaa"), "a"]또한 캡처 그룹의 끝은 닫는 브래킷이 닫혀 있는지 여부에 따라 다릅니다. 예를 들어,/(a/1) {3}/. 첫 번째 캡처 그룹이 /1이 사용될 때 일치하기 시작했지만 아직 끝나지 않았습니다. 이것은 또한 전방 참조이므로 /1 사이의 일치는 여전히 비어 있습니다.
js> /(a/1) {3 }/.exec("aaa")), "a"]Another example:
js> /(? :(O)(O)(O)(O)* (O)|(B)(A)(R)*/.exec("foobar"), 정의되지 않은, 정의되지 않은, "b", "a", "r"] *는 정량 자입니다. 첫 번째 라운드 일치 후 : $ 1은 "F", $ 2는 "O", $ 3은 "O", $ 4는 정의되지 않았으며 $ 5는 undefined 으며 $ 6은 undefined .
두 번째 경기의 시작 부분에서 : 모든 캡처 된 값은 undefined 것으로 재설정됩니다.
두 번째 경기 후 : $ 1은 undefined , $ 2는 undefined , $ 3은 undefined , $ 4는 "b", $ 5는 "a", $ 6는 "r"입니다.
& "foobar"로 할당되며 경기가 끝납니다.
요약
위의 내용은 JavaScript의 규칙 성과 다른 언어의 차이점을 요약 한 전체 컨텐츠입니다. 이 기사의 내용이 모든 사람의 연구와 작업에 도움이되기를 바랍니다.