[regex] 정규식에서 대괄호와 괄호의 차이점은 무엇입니까?
다음은 JavaScript에서 사용하기 위해 만든 정규식입니다.
var reg_num = /^(7|8|9)\d{9}$/
다음은 팀원이 제안한 또 다른 것입니다.
var reg_num = /^[7|8|9][\d]{9}$/
규칙은 전화 번호를 확인하는 것입니다.
- 10 개의 숫자 여야합니다.
- 첫 번째 숫자는 7, 8 또는 9입니다.
답변
다음 정규식은 동일합니다 (일치 목적을 위해).
/^(7|8|9)\d{9}$/
/^[789]\d{9}$/
/^[7-9]\d{9}$/
설명:
-
(a|b|c)
은 정규식 “OR”이며 “a 또는 b 또는 c”를 의미합니다. OR에 필요한 대괄호가 있으면 숫자 도 캡처 됩니다. 엄격히 동일하게하려면 비 캡처 그룹(?:7|8|9)
으로 만들도록 코딩 해야합니다 . -
[abc]
는 “a, b 또는 c의 모든 문자”를 의미하는 “문자 클래스”입니다 (문자 클래스는 범위를 사용할 수 있습니다 (예 :[a-d]
=[abcd]
).)
이러한 정규식이 유사한 이유는 문자 클래스가 “or”(단일 문자에만 해당)의 속기이기 때문입니다. 교대 (abc|def)
로 문자 클래스로 변환되지 않는 것과 같은 작업을 수행 할 수도 있습니다 .
답변
실수를 제외하고 는 팀의 조언이 거의 맞습니다. 그 이유를 알게되면 절대 잊지 못할 것입니다. 이 실수를보세요.
/^(7|8|9)\d{9}$/
이것이하는 일 :
^
그리고$
이러한 앵커 사이의 서브 패턴이 전체 일치하는 것을 주장하는 고정 된 일치를 의미한다. 문자열은 하위 패턴이 섹션뿐만 아니라 전체와 일치하는 경우에만 일치합니다.()
캡처 그룹을 나타냅니다 .7|8|9
중 하나와 일치하는 의미7
,8
또는9
. 또한 이것을 수행 교대 파이프 조작자가 무엇 인|
번갈아 교대 사이 – 않는다. 이것은 교대 사이를 역 추적합니다. 첫 번째 교대가 일치하지 않으면 엔진은 교대 일치 중에 포인터 위치가 이동하기 전에 돌아와 다음 교대를 계속 일치시켜야합니다. 캐릭터 클래스는 순차적으로 진행할 수 있습니다 . 최적화가 비활성화 된 정규식 엔진에서이 일치를 확인하십시오.
Pattern: (r|f)at
Match string: carat
Pattern: [rf]at
Match string: carat
\d{9}
9 자리 숫자와 일치합니다.\d
임의의 숫자와 일치하는 속기 메타 문자입니다.
/^[7|8|9][\d]{9}$/
그것이 무엇을하는지보십시오 :
^
및$
뿐만 아니라 고정 된 일치를 의미한다.[7|8|9]
A는 문자 클래스는 . 목록에서 모든 문자는7
,|
,8
,|
, 또는9
따라서이 일치시킬 수|
잘못에서 추가되었다. 역 추적없이 일치합니다.[\d]
메타 문자에 서식하는 문자 클래스입니다\d
. 문자 클래스와 단일 메타 문자의 조합은 추상 계층이 일치 속도를 늦출 수 있기 때문에 나쁜 생각이지만 이것은 구현 세부 사항 일 뿐이며 일부 정규식 구현에만 적용됩니다. JavaScript는 하나가 아니지만 하위 패턴을 약간 더 길게 만듭니다.{9}
이전 단일 구성이 총 9 번 반복됨을 나타냅니다.
최적의 정규식은입니다 /^[789]\d{9}$/
. /^(7|8|9)\d{9}$/
불필요한 캡처는 대부분의 정규식 구현에서 성능 저하를 초래하기 때문입니다 (자바 스크립트질문 var
이 코드에서 키워드 를 사용한다는 점을 고려하면 아마도 JavaScript 일 것입니다.) 사용PHP프리그 매칭을 위해 PCRE에서 실행되는 것은 역 추적의 부족을 최적화 할 것입니다. 그러나 우리는 PHP에도 없습니다. 따라서 []
교대 대신 클래스 를 사용 |
하면 매치가 역 추적되지 않기 때문에 성능 보너스를 제공하므로 둘 다 사용하는 것보다 더 빨리 이전 정규식.
답변
처음 두 개의 예는 무언가로 대체하는 경우 매우 다르게 작동합니다. 이것에 일치하는 경우 :
str = str.replace(/^(7|8|9)/ig,'');
7 또는 8 또는 9를 빈 문자열로 바꿉니다.
이것에 일치하면
str = str.replace(/^[7|8|9]/ig,'');
당신은 7
또는 8
또는 9
또는 수직 막대를 교체 할 것입니다 !!!! 빈 문자열로.
나는 이것을 어려운 방법으로 발견했습니다.