정규식 학습하기


166

정규 표현식을 실제로 이해하지 못합니다. 따라하기 쉬운 방법으로 설명해 주시겠습니까? 온라인 도구 나 책이 있다면 그 도구들에도 연결할 수 있습니까?

답변:


789

가장 중요한 부분은 개념입니다. 빌딩 블록의 작동 방식을 이해하면 구문의 차이는 가벼운 방언에 지나지 않습니다. 정규식 엔진의 구문 위에있는 레이어는 사용중인 프로그래밍 언어의 구문입니다. Perl과 같은 언어는 이러한 복잡한 문제를 대부분 제거하지만 C 프로그램에서 정규식을 사용하는 경우 다른 고려 사항을 염두에 두어야합니다.

정규식을 원하는대로 혼합하고 일치시킬 수있는 빌딩 블록으로 생각하면 자신의 패턴을 작성하고 디버그하는 방법과 다른 사람이 작성한 패턴을 이해하는 방법을 배우는 데 도움이됩니다.

간단하게 시작

개념 상 가장 간단한 정규식은 리터럴 문자입니다. 패턴 N은 문자 'N'과 일치합니다.

서로 옆에있는 정규식은 시퀀스와 일치합니다. 예를 들어, 패턴 Nick은 시퀀스 'N', 'i', 'c', 'k'순으로 일치합니다.

grep평범한 문자열을 검색하는 경우에도 유닉스를 사용해 본 적이 있다면 이미 정규 표현식을 사용하고있는 것입니다! ( re에서는 grep정규 표현식을 의미합니다.)

메뉴에서 주문

약간의 복잡성을 추가하면 'Nick'또는 'nick'과 pattern을 일치시킬 수 있습니다 [Nn]ick. 대괄호로 묶인 부분은 문자 클래스 이므로 동봉 된 문자 중 하나와 정확히 일치합니다. 문자 클래스에서 범위를 사용할 수도 있으므로 [a-c]'a'또는 'b'또는 'c'와 일치합니다.

패턴 .은 특별합니다. 리터럴 점만 일치시키기보다는 모든 문자 와 일치 합니다 . 실제로 큰 문자 클래스와 개념적으로 같습니다 [-.?+%$A-Za-z0-9...].

캐릭터 클래스를 메뉴로 생각하십시오. 하나만 선택하십시오.

유용한 단축키

를 사용하면 .입력 내용을 많이 절약 할 수 있으며 일반적인 패턴에 대한 다른 바로 가기가 있습니다. 숫자를 맞추고 싶다고 가정 해보십시오 [0-9]. 숫자는 자주 일치하는 대상이므로 바로 가기를 사용할 수 있습니다 \d. 다른 \s문자 는 (공백) 및 \w(단어 문자 : 영숫자 또는 밑줄)입니다.

대문자 변형은 보완이므로 예를 들어 공백이 아닌 문자 \S와 일치합니다 .

한 번이면 충분하지 않습니다

여기에서 수량 자로 패턴의 일부를 반복 할 수 있습니다 . 예를 들어, 한정자는 서브 패턴을 수정하는 서브 패턴을 선택적으로 만들기 ab?c때문에 패턴 은 'abc'또는 'ac'와 일치 ?합니다. 다른 정량자는

  • * (0 회 이상)
  • + (한 번 이상)
  • {n}(정확히 n 번)
  • {n,}(최소 n 회)
  • {n,m}( n 회 이상 m 회 이하)

이 블록 중 일부를 조합하면 패턴 [Nn]*ick

  • ick
  • 새긴 ​​금
  • 새긴 ​​금
  • n 닉
  • (등등)

첫 번째 경기는 중요한 교훈을 보여줍니다. *항상 성공합니다! 모든 패턴은 0 번 일치 할 수 있습니다.

몇 가지 다른 유용한 예 :

  • [0-9]+(및 동등한 \d+)은 음이 아닌 정수와 일치합니다.
  • \d{4}-\d{2}-\d{2} 2019-01-01 형식의 날짜와 일치

그룹화

수량자는 패턴을 바로 왼쪽으로 수정합니다. 0abc+0'0abc0', '0abcabc0'등과 일치 할 것으로 예상 할 수 있지만 플러스 수량 화기 바로 왼쪽의 패턴 은 c입니다. 이는 0abc+0'0abc0', '0abcc0', '0abccc0'등과 일치 한다는 의미 입니다.

하나 이상의 'abc'시퀀스를 끝에 0과 일치 시키려면을 사용하십시오 0(abc)+0. 괄호는 단위로 수량화 할 수있는 하위 패턴을 나타냅니다. 정규식 엔진이 괄호로 묶은 그룹과 일치하는 입력 텍스트 부분을 저장하거나 "캡처"하는 것도 일반적입니다. 이 방법으로 비트를 추출하면 인덱스를 계산하는 것보다 훨씬 유연하고 오류가 적습니다 substr.

교대

이전에는 '닉'또는 '닉'과 일치하는 방법을 보았습니다. 다른 하나는에서와 같이 교대로 있습니다 Nick|nick. 교대에는 왼쪽의 모든 것과 오른쪽의 모든 것이 포함됩니다. 의 범위를 제한하기 위해 괄호를 그룹화 사용 |, 예를 , (Nick|nick).

또 다른 예를 들어, 당신은 동등하게 쓸 수 [a-c]와 같은 a|b|c, 그러나 많은 구현 대안 1보다 큰 길이를 가질 것으로 가정하기 때문에이 가능성이 최적이 될 것입니다.

탈출

일부 문자는 서로 일치하지만 다른 문자는 특별한 의미를 갖습니다. 패턴 \d+이 백 슬래시와 소문자 D, 더하기 부호와 일치하지 않습니다.이를 얻으려면을 사용 \\d\+합니다. 백 슬래시는 다음 문자에서 특별한 의미를 제거합니다.

탐욕

정규식 수량자는 탐욕 스럽습니다. 즉, 전체 패턴을 성공적으로 일치시키면서 가능한 한 많은 텍스트를 일치시킵니다.

예를 들어 입력이

"안녕하세요."그녀는 "어떻게 지내?"

".+"'Hello'만 일치 할 것으로 예상 할 수 있으며 'Hello'에서 'you?'까지 일치한다는 것을 알면 놀라게됩니다.

욕심 많은 것에서 조심스럽게 생각할 수있는 것으로 바꾸려면 ?수량 자에 여분 을 더하십시오. 이제 \((.+?)\)질문의 예가 어떻게 작동 하는지 이해했습니다 . 리터럴 왼쪽 괄호, 하나 이상의 문자 순서 및 오른쪽 괄호로 끝나는 순서와 일치합니다.

입력이 '(123) (456)'이면 첫 번째 캡처는 '123'입니다. 욕심없는 정량자는 나머지 패턴이 가능한 빨리 일치하기를 원합니다.

(혼란에 관해서는, 나는 ((.+?))같은 일을 할 정규식 방언을 모른다 . 나는 어딘가에서 전송에서 무언가가 잃어버린 것 같다.)

앵커

특수 패턴 ^을 사용 하여 입력 시작 부분 $에만 일치시키고 끝 부분에만 일치시킵니다. "앞뒤에 무엇이 있는지 알고 있지만 그 사이에 모든 것을 알려주십시오"라고 말하는 패턴으로 "북 엔드"를 만드는 것은 유용한 기술입니다.

양식의 주석과 일치 시키려고한다고 가정하십시오.

-- This is a comment --

당신은 쓸 것 ^--\s+(.+)\s+--$입니다.

나만의 빌드

정규 표현식은 재귀 적이므로 이제 이러한 기본 규칙을 이해 했으므로 원하는대로 조합 할 수 있습니다.

정규식 작성 및 디버깅 도구 :

서적

무료 자료

각주

† :. 모든 인물과 일치하는 위의 진술 은 엄격하게 사실이 아닌 교육 학적 목적을위한 단순화입니다. 점은 개행을 제외한 모든 문자와 일치 "\n"하지만 실제로 .+개행 경계를 넘는 것과 같은 패턴은 거의 기대하지 않습니다 . Perl 정규 표현식에는 예를 들어 모든 문자를 일치 시키기 위해 /s스위치 와 Java가 있습니다. 이러한 기능이없는 언어의 경우 "공백 또는 비 공백"과 일치 하는 것 , 즉 무엇이든 사용할 수 있습니다.Pattern.DOTALL.[\s\S]


14
또한 시행 착오 방법을 사용할 수 있으며 온라인 정규식 테스터 및 디버거를 따르는 것보다 큰 도움이 될 수 있습니다. regex101.com
Juraj.Lorinc

2
비슷한 패턴에도 불구하고 a{,m}적어도 Javascript, Perl 및 Python에서는 문제가되지 않습니다.
기금 모니카의 소송

2
모든 기능 세트와 구문 규칙이 다른 정규식 엔진에는 여러 종류가 있습니다.
hek2mgl

1
hackr.io/tutorials/learn-regular-expressions-regex 는 최고의 온라인 정규식 자습서를 찾기에 좋은 장소입니다. 여기에있는 모든 자습서는 프로그래밍 커뮤니티에서 제출하고 권장합니다 (SO와 같이 찬성).
Saurabh Hooda

2
이 모든 것을 한마디로 가져 오려는 노력에 감사하십시오.
Saurabh Tiwari
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.