Programing

정규식 학습하기

lottogame 2020. 5. 28. 07:55
반응형

정규식 학습하기


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


가장 중요한 부분은 개념입니다. 빌딩 블록의 작동 방식을 이해하면 구문의 차이는 가벼운 방언에 지나지 않습니다. 정규식 엔진의 구문 위에있는 레이어는 사용중인 프로그래밍 언어의 구문입니다. 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\+. 백 슬래시는 다음 문자에서 특별한 의미를 제거합니다.

탐욕

Regular expression quantifiers are greedy. This means they match as much text as they possibly can while allowing the entire pattern to match successfully.

For example, say the input is

"Hello," she said, "How are you?"

You might expect ".+" to match only 'Hello,' and will then be surprised when you see that it matched from 'Hello' all the way through 'you?'.

To switch from greedy to what you might think of as cautious, add an extra ? to the quantifier. Now you understand how \((.+?)\), the example from your question works. It matches the sequence of a literal left-parenthesis, followed by one or more characters, and terminated by a right-parenthesis.

If your input is '(123) (456)', then the first capture will be '123'. Non-greedy quantifiers want to allow the rest of the pattern to start matching as soon as possible.

(As to your confusion, I don't know of any regular-expression dialect where ((.+?)) would do the same thing. I suspect something got lost in transmission somewhere along the way.)

Anchors

Use the special pattern ^ to match only at the beginning of your input and $ to match only at the end. Making "bookends" with your patterns where you say, "I know what's at the front and back, but give me everything between" is a useful technique.

Say you want to match comments of the form

-- This is a comment --

you'd write ^--\s+(.+)\s+--$.

Build your own

Regular expressions are recursive, so now that you understand these basic rules, you can combine them however you like.

Tools for writing and debugging regexes:

Books

Free resources

Footnote

†: The statement above that . matches any character is a simplification for pedagogical purposes that is not strictly true. Dot matches any character except newline, "\n", but in practice you rarely expect a pattern such as .+ to cross a newline boundary. Perl regexes have a /s switch and Java Pattern.DOTALL, for example, to make . match any character at all. For languages that don't have such a feature, you can use something like [\s\S] to match "any whitespace or any non-whitespace", in other words anything.

참고URL : https://stackoverflow.com/questions/4736/learning-regular-expressions

반응형