Refrex!ES2018의 캡처 및 비캡처 그룹
이것은 그리 나쁘지 않다, 그렇지?
어쨌든 우리는 기초 지식부터 시작해서 포획과 비포획조에 들어가자.
이것은 내가 가지고 있는 임무이다. 나는 특정 영역의 전체 호스트, 하위 영역과 URL 경로를 추출해야 한다(본 연습을 위해 사용하겠다
google.com
.다음과 같은 모든 가능성에 대해 작업해야 합니다.
www.google.com/search?q=devto
//www.google.com
http://www.google.com
https://www.google.com/search?q=devto
mail.google.com
something.like.google.com/for-me
나는 정규 표현식에 대해 약간 생소하지만, 나는 몇 가지 일을 기억한다./
로 구분된다./
사이에 정규 표현식 모드를 배치하고 두 번째/
다음에 로고를 배치합니다. 예를 들어 i
대소문자 삽입 또는 g
전역을 표시합니다..
와 .
를 사용하려면 문자류와 정규 표현식 구분자와 혼동되지 않도록 의미를 바꿔야 한다.그리고 use/
와\.
를 사용해야 합니다.\/
(0 또는 1회 출현), ?
(0 또는 그 이상 출현), *
(1 또는 그 이상 출현)이 있다.+
함수를 사용할 때, 그것들도 포착되어 단독으로 되돌아온다.const regex = /((https?:)?\/\/)?(.*)\.google\.com(.*)/i;
우리는 그것을 몇 부분으로 분해합시다.우선, 협의:match
- 이것은 포획https?
또는http
을 할 것이다.알파벳's'는 여기에서 선택할 수 있습니다. 왜냐하면 우리가 사용하기 때문입니다https
.s?
- 전체 그룹이 선택할 수 있기 때문에 포획(https?:)?
, http:
또는 아무것도 포획하지 않습니다.https:
- 슬래시 캡처 프로토콜을 사용합니다. 슬래시는 ((https?:)?\/\/)?
, http://
, https://
또는 아무것도 아닙니다. 전체 그룹은 선택할 수 있기 때문입니다.//
- 하위 도메인 캡처(.*)
- 일치 \.google\.com
.google.com
- 경로 캡처(.*)
URL을 사용할 때 다음과 같은 결과를 얻을 수 있습니다.'https://www.google.com/search?q=devto'.match(regex);
// Result:
{
0: "https://www.google.com/search?q=devto",
1: "https://",
2: "https:",
3: "www",
4: "/search?q=devto",
groups: undefined,
index: 0,
input: "https://www.google.com/search?q=devto",
length: 5
}
반환된 개체에서 요소 0은 완전히 일치하는 결과이며, 그 다음의 모든 디지털 요소는 정규 표현식에 나타난 각 포획 그룹에 순서대로 대응합니다.지금까지는 3조의 하위 영역, 4조의 경로, 1조+
match
+4조를 조합한 전체 호스트를 볼 수 있었기 때문에 지금은 다음과 같은 함수를 작성할 수 있습니다.function extract(url) {
const regex = /((https?:)?\/\/)?(.*)\.google\.com(.*)/i;
const match = url.match(regex);
let result = {};
if (match !== null) {
result = {
host: `${match[1]}${match[3]}.google.com`,
subdomain: match[3],
path: match[4]
};
}
return result;
}
그런 다음 다음을 사용합니다.extract('https://www.google.com/search?q=devto');
// Result:
{
host: "https://www.google.com",
path: "/search?q=devto",
subdomain: "www"
}
그러나 이것은 많지 않은 것 같다DRY.결과에 대한 연결과 부분에 대한 하드코딩 .google.com
이 필요 없이 정규 표현식에서 온전한 호스트를 직접 얻을 수 있을 것 같다.그래서 전체 호스트를 캡처하기 위해 다른 그룹을 추가했습니다.
const regex = /(((https?:)?\/\/)?(.*)\.google\.com)(.*)/i;
'https://www.google.com/search?q=devto'.match(regex);
// Result:
{
0: "https://www.google.com/search?q=devto",
1: "https://www.google.com",
2: "https://",
3: "https:",
4: "www",
5: "/search?q=devto",
groups: undefined,
index: 0,
input: "https://www.google.com/search?q=devto",
length: 6
}
아름답다이제 전체 호스트는 그룹 1, 하위 도메인은 그룹 4, 경로는 그룹 5로, 내 함수는 다음과 같이 단순화됩니다.function extract(url) {
const regex = /(((https?:)?\/\/)?(.*)\.google\.com)(.*)/i;
const match = url.match(regex);
let result = {};
if (match !== null) {
result = {
host: match[1],
subdomain: match[4],
path: match[5]
};
}
return result;
}
지금까지 줄곧 괜찮았어!하지만 자세히 보면 2조와 3조는 정말 필요 없어요.그것들의 존재는 단지 우리가 그것들 주위에서 양사를 사용하고 싶기 때문일 뿐이지만, 우리는 그것들의 값을 단독으로 얻는 것에 대해 조금도 흥미를 느끼지 않는다.기본적으로 모든 그룹을 캡처하기 때문입니다.그리고 저는 여기서 dev.to에 대해 연구를 했는데 이 좋은 글을 발견했습니다.
TIL: 정규 표현식의 비캡처 그룹
스토퍼 주디스・ 2018년 5월 16일・ 2분 읽기
이제 나는 모든 그룹을 비포획조로 전환할 수 있다는 것을 알게 되었다. 단지 그 앞에
.google.com
!감사합니다.!
이제 2조와 3조가 잡히지 않도록 하겠습니다.
const regex = /((?:(?:https?:)?\/\/)?(.*)\.google\.com)(.*)/i;
'https://www.google.com/search?q=devto'.match(regex);
// Result:
{
0: "https://www.google.com/search?q=devto",
1: "https://www.google.com",
2: "www",
3: "/search?q=devto",
groups: undefined,
index: 0,
input: "https://www.google.com/search?q=devto",
length: 4
}
봐라!이제 그룹 1을 전체 호스트로, 그룹 2를 하위 도메인으로, 그룹 3을 경로로 사용합니다.우리는 상응하는 함수?:
를 다시 쓸 수 있다.하지만 그 전에 케이크 위의 설탕 크림을 만들어 봅시다!ES2018 도입named capture groups은 이제 각 그룹을 이름으로 참조할 수 있음을 의미합니다.문법은 각 그룹의 시작에 덧붙인다
extract
.따라서 이제 정규 표현식은 다음과 같이 실행됩니다.
const regex = /(?<host>(?:(?:https?:)?\/\/)?(?<subdomain>.*)\.google\.com)(?<path>.*)/i;
'https://www.google.com/search?q=devto'.match(regex);
// Result:
{
0: "https://www.google.com/search?q=devto",
1: "https://www.google.com",
2: "www",
3: "/search?q=devto",
groups: {
host: "https://www.google.com",
path: "/search?q=devto",
subdomain: "www"
},
index: 0,
input: "https://www.google.com/search?q=devto",
length: 4
}
마지막으로 우리의 ?<name>
함수는 좀 간단해졌다.function extract(url) {
const regex = /(?<host>(?:(?:https?:)?\/\/)?(?<subdomain>.*)\.google\.com)(?<path>.*)/i;
const match = url.match(regex);
return match !== null? match.groups: {};
}
DISCLAIMER: the concept of "simpler" here can be subjective. Typically, there is a trade-off between regex complexity and code complexity. In this case, we are writing a more complex regex to favor less complex code.
Long story short, my recommendation is so you don't take this way too seriously and use your best judgment to never go too extreme. Remember: you write code for humans, which will have to maintain it even after you are gone. Thus, it doesn't really help much if you have the most elegant code ever written with the most complex regex ever.
명명된 포획 그룹을 사용하면 Backreferences 및 Replacement targets 에서 더 많은 작업을 할 수 있습니다.
역인용은 또 다른 괴물이다. 나는 다음 글에서 이 점을 소개할 계획이다.하지만 대상을 바꾸는 것은 더 간단합니다. 포획 그룹을 명명했을 때 문자열
extract
함수의 대상에서 사용할 수 있음을 의미합니다.구문은 대상 문자열에서 사용됩니다 replace
.예를 들어, 대체된 문자열에서 캡처
$<name>
를 사용합니다.const regex = /(?<host>(?:(?:https?:)?\/\/)?(?<subdomain>.*)\.google\.com)(?<path>.*)/i;
'https://www.google.com/search?q=devto'.replace(regex, 'subdomain: $<subdomain>');
// Result
'subdomain: www'
그렇습니다, 점원들!나는 네가 매우 사람을 진작시키는 하루를 쉬기를 바란다.
Reference
이 문제에 관하여(Refrex!ES2018의 캡처 및 비캡처 그룹), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/themindfuldev/refrex-capture-and-non-capture-groups-in-es2018-3nj7텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)