정규 표현식이란 무엇입니까?
정규식이라고도 하는 정규식은 문자열 내의 특정 문자나 단어를 검색하는 데 사용할 수 있는 패턴을 정의하여 작동합니다.
사용하려는 패턴을 정의한 후에는 편집하고, 특정 문자나 단어를 삭제하고, 특정 패턴을 포함하는 파일이나 문자열에서 관련 정보를 추출하는 등의 작업을 수행할 수 있습니다.
정규식을 배워야 하는 이유
Regex를 사용하면 많은 시간을 절약할 수 있는 방식으로 텍스트 처리를 수행할 수 있습니다. 그 과정에서 재미를 느낄 수도 있습니다.
정규식을 사용하면 정보를 훨씬 쉽게 찾을 수 있습니다. 대상을 찾으면 일괄 편집/재플레이트/삭제 또는 필요한 모든 처리를 수행할 수 있습니다.
정규 표현식을 사용하는 실제적인 예로는 배치 파일 이름 바꾸기, 로그 구문 분석, 양식 유효성 검사, 코드베이스에서 대량 편집, 재귀 검색 등이 있습니다.
이 튜토리얼에서는 이 사이트의 도움을 받아 정규식 기본 사항을 다룰 것입니다. 나중에 Python을 사용하여 해결할 수 있는 몇 가지 정규식 문제를 소개하겠습니다. 또한 sed와 같은 도구를 사용하는 방법도 보여 드리겠습니다. 그리고 grep 정규식으로.
인생의 많은 일과 마찬가지로 정규식은 실제로 실행해야만 이해할 수 있는 것 중 하나입니다. 이 기사를 읽으면서 정규식을 시험해 보시기 바랍니다.
목차
- 정규식 기본
- 정확히 일치
- 문자 세트
- 정규식의 일치 범위
- 세트에 없는 문자와 일치
- 문자 클래스
- 수량자
- 캡처 그룹
- 정규식에서 논리 OR을 사용하는 방법
- 캡처 그룹을 참조하는 방법
- 캡처 그룹 이름 지정 방법
- 명령줄 도구에서 정규식을 사용하는 방법
- grep을 사용한 재귀 정규식 검색
- sed로 대체
- 고급 정규식:둘러보기
- 뒤돌아보기
- 예측
- 정규식의 실제 예
- 로그 파싱
- 대량 파일 이름 바꾸기
- 이메일 확인
- 비밀번호 제약
- 마지막 한마디
정규식 기본
정규식은 패턴과 일치하는 일련의 문자일 뿐입니다. 리터럴 문자(예:'abc')를 사용하는 것 외에도 특별한 목적을 갖는 일부 메타 문자(*,+,? 등)가 있습니다. 정규식을 단순화하는 데 도움이 되는 문자 클래스와 같은 기능도 있습니다.
정규식을 작성하기 전에 찾고 있는 패턴에 대한 모든 기본 사례와 극단적 사례에 대해 배워야 합니다.
예를 들어, 'Hello World'와 일치시키려는 경우 줄이 'Hello'로 시작되기를 원합니까, 아니면 다른 것으로 시작할 수 있습니까? 'Hello'와 'World' 사이에 정확히 하나의 공백을 원하십니까, 아니면 더 있을 수 있습니까? 'World' 뒤에 다른 문자가 올 수 있나요? 아니면 줄이 거기서 끝나야 하나요? 대소문자 구분에 신경쓰시나요? 등등.
정규 표현식을 작성하기 전에 답을 얻어야 하는 질문 유형입니다.
정확히 일치
가장 기본적인 정규식 형식은 텍스트 편집기에서 Ctrl-F를 사용하는 것과 유사한 방식으로 문자 시퀀스를 일치시키는 것입니다.
상단에는 일치하는 항목의 수가 표시되고 하단에는 정규 표현식이 문자별로 무엇과 일치하는지에 대한 설명이 제공됩니다.
문자 세트
정규식 문자 집합을 사용하면 문자 그룹의 문자 하나와 일치시킬 수 있습니다. 그룹은 대괄호 []로 둘러싸여 있습니다.
예를 들어 t[ah]i "tai" 및 "thi"와 일치합니다. 여기서 't'와 'i'는 고정되어 있지만 그 사이에 'a' 또는 'h'가 나타날 수 있습니다.
정규식의 일치 범위
때로는 대문자 영어와 같이 본질적으로 순차적인 문자 그룹을 일치시키고 싶을 수도 있습니다. 하지만 26개의 편지를 모두 쓰는 것은 꽤 지루할 것입니다.
Regex는 범위를 사용하여 이 문제를 해결합니다. "-"는 범위 연산자 역할을 합니다. 일부 유효한 범위는 다음과 같습니다:
범위 일치 [A-Z]대문자[a-z]소문자[0-9]모든 숫자
[b-e]와 같은 부분 범위를 지정할 수도 있습니다. 문자 'bcde' 또는 [3-6] 중 하나와 일치시키려면 숫자 '3456' 중 하나와 일치합니다.
문자 집합 내에서 하나의 범위만 지정하도록 제한되지는 않습니다. 여러 범위를 사용할 수 있으며 다른 추가 문자와 결합할 수도 있습니다. 여기 [3-6u-w;] '3456uvw' 또는 세미콜론 ';' 중 하나와 일치합니다.
세트에 없는 문자와 일치
집합 앞에 '^'를 붙이면 반대 작업이 수행됩니다. 예를 들어 [^A-Z0-9] 대문자와 숫자를 제외한 모든 문자와 일치합니다.
문자 클래스
정규식을 작성하는 동안 숫자와 같은 특정 그룹을 매우 자주 일치시키고 동일한 표현식에서도 여러 번 일치시켜야 합니다.
예를 들어 '문자-숫자-문자-숫자'와 같은 패턴을 어떻게 일치시키겠습니까?
지금까지 배운 내용으로 [a-zA-Z]-[0-9]-[a-zA-z]-[0-9]을 생각해 낼 수 있습니다. . 이것은 효과가 있지만 패턴 길이가 길어짐에 따라 표현식이 얼마나 지저분해질 수 있는지 알 수 있습니다.
표현을 더 간단하게 만들기 위해 숫자와 같이 잘 정의된 문자 그룹에 클래스가 할당되었습니다. 다음 표에서는 이러한 클래스와 문자 세트가 포함된 해당 표현식을 보여줍니다.
ClassMatches동등 표현식 .newline[^\n\r]\wword 문자[a-zA-Z0-9_]\W단어가 아닌 문자[^\w]\ddigits[0-9]\Dnon-digits[^\d]\sspace, tab, newlines[ \t\r\n\f]\Snon 공백 문자[^\s]를 제외한 모든 것문자 클래스는 매우 편리하며 표현을 훨씬 깔끔하게 만들어줍니다. 이 튜토리얼 전체에서 이를 광범위하게 사용할 것이므로 이 표를 참조 지점으로 사용하고 클래스 중 하나라도 잊어버린 경우 여기로 다시 돌아올 수 있습니다.
대부분의 경우 패턴의 모든 위치에 대해서는 신경 쓰지 않습니다. "." 클래스를 사용하면 가능한 모든 문자를 세트로 작성하지 않아도 됩니다.
예를 들어 t.. t로 시작하고 그 뒤에 있는 두 문자와 일치합니다. 이는 SQL LIKE를 생각나게 할 수 있습니다. t%%을 사용하는 연산자 같은 일을 하기 위해.
정량자
'패턴'과 '반복'이라는 단어는 함께 사용됩니다. 3자리 숫자를 일치시키려면 \d\d\d을 사용하면 됩니다. . 하지만 11자리 숫자를 일치시켜야 한다면 어떻게 될까요? '\d'를 11번 쓸 수 있지만, 정규식을 작성하거나 어떤 종류의 프로그래밍을 할 때 일반적으로 경험에 따르면 무언가를 두 번 이상 반복하는 경우 어떤 기능을 인식하지 못할 수도 있습니다.
정규식에서는 이 목적으로 수량자를 사용할 수 있습니다. 11자리 숫자를 일치시키려면 \d{11}라는 표현식을 쓰면 됩니다. .
아래 표에는 정규식에서 사용할 수 있는 수량자가 나열되어 있습니다.
정량자 일치 *0 이상?0 또는 1+1 이상{n}정확히 n회{n, }n회 이상{n, m}n~m회 포함
이 예에서 can\s+write 표현식은 can과 일치 그 뒤에 1개 이상의 공백, write . 하지만 'canwrite'가 \s+와 일치하지 않는 것을 볼 수 있습니다. 적어도 하나의 공백이 일치해야 함을 의미합니다. 잘리지 않은 텍스트를 검색할 때 유용합니다.
can\s?write가 무엇인지 추측할 수 있나요? 일치할까요?
캡처 그룹
캡처 그룹은 괄호()로 묶인 하위 표현식입니다. 캡처 그룹은 원하는 만큼 가질 수 있으며 중첩된 캡처 그룹도 가질 수 있습니다.
(The ){2} 표현식 'The'가 두 번 일치합니다. 그러나 캡처 그룹이 없으면 The {2} 표현식은 수량사는 'The'에 그룹으로 적용되지 않고 공백 문자에 적용되므로 'The' 뒤에 공백 2개가 오는 것과 일치합니다.
유효한 정규식과 마찬가지로 캡처 그룹 내의 모든 패턴을 일치시킬 수 있습니다. 여기 (is\s+){2} 'is' 뒤에 1개 이상의 공백이 두 번 나오는 경우 일치합니다.
정규식에서 논리 OR을 사용하는 방법
"|"를 사용할 수 있습니다. 여러 패턴을 일치시킵니다. This is (good|bad|sweet) 'This is ' 다음에 'good', 'bad' 또는 'sweet' 중 하나가 옵니다.
여기서도 캡처 그룹의 중요성을 이해해야 합니다. This is good|bad|sweet 표현식이 무엇인지 생각해 보세요. 일치할까요?
캡처 그룹을 사용하면 good|bad|sweet This is에서 격리되었습니다. . 그러나 캡처 그룹 내부에 없으면 전체 정규식은 단 하나의 그룹입니다. 따라서 This is good|bad|sweet라는 표현은 문자열에 'This is good', 'bad' 또는 'sweet'이 포함되어 있으면 일치합니다.
캡처 그룹 참조 방법
캡처 그룹은 교체 탭에서 볼 수 있듯이 동일한 표현식에서 또는 교체를 수행하는 동안 참조될 수 있습니다.
대부분의 도구와 언어를 사용하면 '\n'으로 n번째 캡처된 그룹을 참조할 수 있습니다. 이 사이트에서는 교체를 참조할 때 '$n'을 사용합니다. 대체 구문은 사용 중인 도구나 언어에 따라 달라집니다. 예를 들어 JavaScript의 경우 '$n'이고 Python의 경우 '\n'입니다.
(This) is \1 power 표현식에서 , 'This'가 캡처된 다음 '\1'로 참조되어 This is This power와 효과적으로 일치합니다. .
캡처 그룹 이름 지정 방법
(?<name>pattern) 구문을 사용하여 캡처 그룹의 이름을 지정할 수 있습니다. \k<name>을 사용하여 동일한 표현식으로 역참조합니다. .
교체 시 참조는 $<name>에 의해 수행됩니다. . 이는 JavaScript의 구문이며 언어마다 다를 수 있습니다. 여기에서 차이점을 알아볼 수 있습니다. 또한 일부 언어에서는 이 기능을 사용하지 못할 수도 있습니다.
(?<lang>[\w+]+) is the best but \k<lang> .* 표현식에서 , 패턴 [\w+]+ 'lang'이라는 이름으로 캡처되고 \k<lang>으로 역참조됩니다. . 이 패턴은 모든 단어 문자 또는 '+' 문자와 1회 이상 일치합니다. .* 정규식 끝에서 임의의 문자와 0회 이상 일치합니다. 그리고 마지막으로 교체 시 $<lang>에 의해 참조가 수행됩니다. .
터미널에서 정규식을 수행할 수 있는 유용한 CLI 도구가 있습니다. 이러한 도구를 사용하면 일부 언어로 코드를 작성한 다음 이를 컴파일하거나 해석하지 않고도 다양한 정규식을 쉽게 테스트할 수 있으므로 시간이 훨씬 더 절약됩니다.
잘 알려진 도구로는 grep, sed 및 awk가 있습니다. 이러한 도구를 활용하는 방법에 대한 아이디어를 제공하기 위해 몇 가지 예를 살펴보겠습니다.
grep을 사용한 재귀 정규식 검색
grep을 통해 정규식의 강력한 기능을 실행할 수 있습니다. Grep은 파일에서 패턴을 검색하거나 재귀 검색을 수행할 수 있습니다.
Windows를 사용하는 경우 Winget을 사용하여 grep을 설치할 수 있습니다. Powershell에서 다음 명령을 실행하세요:
winget install -e --id GnuWin32.Grep
우리 대학에서 CTF 대회를 위해 만든 과제에 대한 솔루션을 보여 드리겠습니다.
챌린지에 첨부된 파일은 여러 수준의 디렉터리와 그 안에 많은 파일이 포함된 zip 파일입니다. 대회 이름은 플래그 형식이 coderush{flag is here}인 Coderush였습니다. . 따라서 coderush{.*} 패턴을 검색해야 합니다. 이는 플래그 형식 coderush{any character here}와 일치합니다. .
unzip ripG.zip으로 파일의 압축을 풉니다. cd ripG로 CD를 입력하세요. .
358개의 디렉터리와 8731개의 파일이 있습니다. 파일의 패턴을 하나씩 검색하는 대신 다음과 같이 grep을 사용할 수 있습니다:
grep --color -R "coderush{.*}"
"-R" 플래그는 재귀 검색을 활성화합니다.
여기에서 grep 및 해당 명령줄 옵션에 대해 자세히 알아볼 수 있습니다.
sed로 대체
sed를 사용하면 정규식을 지정하여 텍스트 파일에 대한 삽입, 삭제, 대체를 수행할 수 있습니다. Windows를 사용하는 경우 여기에서 sed를 얻을 수 있습니다. 또는 WSL을 사용하는 경우 grep 및 sed와 같은 도구를 이미 사용할 수 있습니다.
sed의 가장 일반적인 사용법은 다음과 같습니다:
sed 's/pattern/replacement/g' filename
echo "${text}" | sed 's/pattern/replacement/g'
여기서는 모든 항목을 대체하기 위해 "g" 옵션이 지정되었습니다.
다른 유용한 옵션은 -n입니다. 모든 줄을 인쇄하는 기본 동작을 억제하고 g 대신 p를 사용하여 정규식의 영향을 받는 줄만 인쇄합니다.
texts.txt의 내용을 살펴보겠습니다.
Hello rand chars World 56 rand chars
Henlo 52 rand chars W0rld rand chars
GREP rand chars Henlo 62 rand chars
Henlo 10 rand chars Henlo rand chars
GREP rand chars Henlo 45 rand chars
우리의 임무는 Henlo number을 대체하는 것입니다. Hello number으로 "GREP"이 있는 줄에서만 가능합니다. 그래서 우리는 Henlo ([0-9]+) 패턴을 검색하고 있습니다. 이는 'Henlo' 뒤에 하나 이상의 숫자가 오는 것과 일치하며 모든 숫자가 캡처됩니다. 그러면 대체 문자열은 Hello \1가 됩니다. – '\1'은 숫자가 포함된 캡처 그룹을 참조합니다.
이를 달성하는 한 가지 방법은 grep을 사용하여 "GREP"이 있는 줄을 grep한 다음 sed로 교체하는 것입니다.
grep "GREP" texts.txt | sed -En 's/Henlo ([0-9]+)/Hello \1/p'
"-E" 옵션을 사용하면 괄호를 이스케이프 처리해야 하는 확장 정규식을 사용할 수 있습니다.
아니면 그냥 sed를 사용해도 됩니다. /pattern/ 사용 패턴이 있는 줄에서만 대체를 제한합니다.
sed -En '/GREP/ s/Henlo ([0-9]+)/Hello \1/p' texts.txt
고급 정규식:둘러보기
Lookaheads 및 Lookbehinds(함께 Lookaround로 알려짐)는 패턴을 일치 항목에 포함하지 않고도 패턴의 존재 여부를 확인할 수 있는 정규식 기능입니다.
너비가 0인 어설션으로 생각할 수 있습니다. 즉, 패턴의 존재를 어설션하지만 일치 항목에서 어떤 문자도 사용하지 않습니다. 이는 매우 강력한 기능이지만 계산 비용도 많이 듭니다. 따라서 자주 사용하는 경우 성능에 주의를 기울이십시오.
뒤돌아보기
'linux'라는 단어를 일치시키고 싶지만 2가지 조건이 있다고 가정해 보겠습니다.
- 'GNU'라는 단어는 'linux'가 나타나기 전에 와야 합니다. 줄에 'linux'가 포함되어 있지만 앞에 'GNU'가 없으면 해당 줄을 삭제하고 싶습니다.
linux만 일치시키려고 합니다. 그 외에는 아무것도 없습니다.
우리는 첫 번째 조건을 만족시키는 방법을 이미 알고 있습니다. GNU.* 'GNU' 뒤에 임의 개수의 문자가 오는 것과 일치합니다. 그런 다음 마지막으로 linux라는 단어를 일치시킵니다. . 이는 GNU-any-characters-linux과 모두 일치합니다. .
하지만 GNU.* 일치를 방지하려면 어떻게 해야 하나요? 1번 조건을 유지하면서요?
여기서 긍정적인 뒤돌아보기가 필요합니다. ?<= 접두사를 붙여 캡처 그룹을 긍정적인 뒤돌아보기로 표시할 수 있습니다. . 이 예에서 표현식은 (?<=GNU.*)linux가 됩니다. .
이제 linux만 가능 일치하고 다른 것은 없습니다.
(?<=GNU.*)linux 표현식에 유의하세요. 및 linux(?<=GNU.*) 똑같이 행동할 것입니다. 두 번째 표현에서는 linux이지만 룩비하인드 이전에 .*가 있습니다. linux와 일치하는 'GNU' 뒤에 . 이는 뒤돌아보기를 만족한다는 것을 의미합니다.
더 간단하게 만들려면 뒤를 돌아보지 않고 패턴을 생각해 보세요. 패턴 GNU.* 'GNU' 및 그 뒤의 모든 항목과 일치합니다. 우리의 경우 linux과 일치합니다. .
이제 (?<=C)X 표현식이라는 일반화된 진술을 도출할 수 있습니다. 패턴 X와 일치합니다. 패턴 C가 X 앞에 오는 경우에만 해당됩니다(그리고 C는 일치에 포함되어서는 안 됩니다).
첫 번째 조건을 뒤집을 수도 있습니다. linux 단어가 포함된 행 일치 GNU인 경우에만 그 전에는 온 적이 없습니다. 이를 부정적인 뒤돌아보기라고 합니다. 이 경우 접두사는 ?<!입니다. . 이전 표현식의 반대는 (?<!GNU.*)linux입니다. .
미리보기
Lookaheads는 이전 예제에서 본 것처럼 LookBehinds와 같은 어설션이기도 합니다. 유일한 차이점은 뒤돌아보기는 먼저 주장을 하고, 미리보기는 나중에 주장한다는 것입니다.
다음 두 가지 조건이 있다고 가정해 보겠습니다.
Hello일치World인 경우에만 그 뒤에 어딘가에 옵니다.- Hello만 일치하고 다른 것은 일치하지 않습니다.
긍정적인 예측의 접두사는 ?=입니다. . Hello(?=.*World) 표현식 두 가지 조건을 모두 충족하게 됩니다. 이는 Hello.*World과 유사합니다. Hello만 제외 일치하는 반면 Hello.*World 'Hello', 'World' 및 그 사이의 모든 항목과 일치합니다.
긍정적인 뒤돌아보기의 예와 유사하게 Hello(?=.*World) 표현식은 및 (?=.*World)Hello 동등합니다. 왜냐하면 .* 'World'가 Hello와 일치하기 전 , 첫 번째 조건을 만족합니다.
부정적인 예견은 부정적인 예견의 보완일 뿐입니다. ?! 접두사를 붙여서 사용할 수 있습니다. . (?!World)Hello Hello과 일치합니다. World가 없는 경우에만 그 이후 아무데나.
다음은 패턴 X를 주장 C와 일치시키려는 경우 탐색을 위한 구문 요약입니다.
OperationRegEx 긍정적인 예측(?=C)X 부정적 예측(?!C)X 긍정적인 뒷모습(?<=C)X 부정적인 뒤돌아보기(?<!C)X 로그 파싱
이 로그 파일에서 우리가 관심을 갖는 라인은 다음과 같습니다:
[1/10000] Train loss: 11.30368, Valid loss: 8.95446, Elapsed_time: 7.58941
[500/10000] Train loss: 0.96180, Valid loss: 0.20098, Elapsed_time: 82.48651
[1000/10000] Train loss: 0.04051, Valid loss: 0.11927, Elapsed_time: 156.86243
우리의 임무는 시대에 따른 손실을 그리는 것과 같은 목적으로 훈련 손실과 검증 손실을 추출하는 것입니다. 11.30368, 0.96180, 0.04051와 같은 훈련 손실 값을 추출해야 합니다. 배열에 넣으세요.
모든 관련 값에는 'Train loss: 접두사가 붙습니다. '이므로 정규 표현식에서 그대로 사용할 수 있습니다. 부동 소수점 숫자를 일치시키려면 ".가 뒤에 오는 숫자 몇 개를 일치시켜야 합니다. " 다음에는 더 많은 숫자가 이어집니다. \d+\.\d+로 이 작업을 수행할 수 있습니다. . 우리는 이 숫자를 추적하고 싶기 때문에 캡처 그룹 내에 있어야 합니다.
"." "."를 일치시키려는 경우 정규식에서 특별한 목적이 있습니다. 문자를 백슬래시로 이스케이프해야 합니다. 이는 특별한 목적을 가진 모든 캐릭터에 적용됩니다. 하지만 문자 집합 내에서 이스케이프할 필요는 없습니다.
종합적으로 training loss를 추출하는 표현식은 Train loss: (\d+\.\d+) 입니다. . 동일한 논리를 사용하여 Valid loss: (\d+\.\d+)로 유효성 검사 손실을 추출할 수 있습니다. .
Python을 사용하여 이 정보를 추출하는 한 가지 방법은 다음과 같습니다.
import re
f = open("log_train.txt", "r").read()
train_loss = re.findall(r'Train loss: (\d+\.\d+)', f)
valid_loss = re.findall(r'Valid loss: (\d+\.\d+)', f)
train_loss = [float(i) for i in train_loss]
valid_loss = [float(i) for i in valid_loss]
print("train_loss =", train_loss)
print("")
print("valid_loss =", valid_loss)
캡처 그룹이 1개인 경우 re.findall 모든 행을 검색하고 캡처 그룹 내부의 값을 목록으로 반환합니다.
모든 정규식 함수는 문자열만 반환하므로 값은 부동 소수점으로 변환되어 인쇄됩니다. 그런 다음 다른 Python 스크립트에서 부동 소수점 목록으로 직접 사용할 수 있습니다.
결과는 다음과 같습니다:
sed를 사용하여 출력을 train_losses.txt에 저장하고 파일에서 읽을 수도 있습니다. 먼저 '/Train/'을 사용하여 'Train'이 있는 줄만 대상으로 삼은 다음 이전과 동일한 정규식을 적용합니다.
sed -En '/Train/ s/.*Train loss: ([0-9]+\.[0-9]+).*/\1/p' log_train.txt | tee train_losses.txt
sed가 모든 관련 행의 내용과 일치하도록 ".*"가 시작과 끝에 추가됩니다. 그런 다음 전체 줄이 캡처 그룹의 값으로 대체됩니다. tee 명령은 sed의 출력을 train_losses.txt로 리디렉션하는 동시에 터미널의 내용을 인쇄하는 데 사용됩니다.
잠시 시간을 내어 에포크를 추출하려면 무엇이 필요한지 생각해 보세요. 이러한 모든 라인에 대해 [500/10000]에서 500을 추출해야 합니다. 배열은 [1, 500, 1000, 1500, ...]과 같아야 합니다. 이전 예제에서 사용한 것과 동일한 접근 방식을 따를 수 있습니다.
"[을 일치시키려면 주의하세요. " 또는 "] ", 탈출해야 해. 여기에 답이 있습니다.
대량 파일 이름 바꾸기
임의의 값이 접두사로 포함된 파일이 있습니다. 모든 파일의 이름을 1.mp4, 2.mp4 등으로 바꿔야 합니다. 이렇게 파일이 생성되었습니다.
이는 이름에 일련 번호가 포함된 파일 목록이 있지만 원하지 않는 다른 문자도 포함되어 있는 일반적인 시나리오입니다.
패턴은 에피소드, 밑줄, 숫자 및 끝에 .mp4까지 일치해야 합니다.
관련 값은 캡처 그룹 내에 넣을 '.mp4' 앞의 숫자입니다. .*Episode_ 숫자까지 모든 것을 일치시킵니다. 그런 다음 ([0-9]+)로 숫자를 캡처할 수 있습니다. 또한 .mp4를 \.mp4와 일치시킵니다. .
따라서 최종 정규식은 .*Episode_([0-9]+)\.mp4입니다. . 우리는 .mp4를 유지하고 싶기 때문에 대체 문자열은 \1.mp4입니다. .
이는 sed를 사용하여 해결하는 한 가지 방법입니다.
for i in *.mp4; do
newname=$(echo $i | sed -En 's/.*Episode_([0-9]+)\.mp4/\1.mp4/p')
mv $i $newname
done;ls
먼저 새 이름이 변수에 저장된 다음 mv 명령을 사용하여 파일 이름을 바꿉니다.
방금 .*를 사용했을까요? .*Episode_ 대신 ? 이 예에서는 그렇습니다. 하지만 Steins_Gate0.mp4와 같은 파일 이름이 있을 수 있습니다. 여기서 0 은 영화 이름의 일부이고 이 파일의 이름을 바꾸고 싶지 않을 것이므로 항상 최대한 구체적으로 지정하는 것이 좋습니다.
일부 파일의 이름이 "Random_Episode6.mp4"로 지정되면 어떻게 되나요? 차이점은 에피소드 뒤에 밑줄이 없다는 것입니다. 어떤 변화를 취해야 합니까?
대답은 "?"를 추가해야 한다는 것입니다. "_" 뒤에 선택사항으로 만듭니다. 정규식은 .*Episode_?([0-9]+)\.mp4입니다. .
이메일 확인
이메일 검증에는 온갖 종류의 복잡한 정규식이 있습니다.
다음은 간단한 것입니다:^[^@ ]+@[^@.]+\.\w+$ . A@B.C 형식과 일치합니다.
아래 표는 이 패턴을 더 작은 조각으로 나눕니다:
패턴 일치^ 줄 시작[^@ ]+ "@" 및 공백 문자@[^@.]+를 제외한 모든 항목 @ 뒤에는 "@" 및 "."을 제외한 모든 항목이 옵니다. 문자\.\w+ "." 그 뒤에 단어 문자$가 옵니다. 줄 끝
정규식 사이트의 오른쪽 상단에 있는 플래그 탭에서 여러 줄 플래그를 활성화할 수 있습니다. 끝에 있는 'gm'은 여러 줄 플래그가 활성화되었음을 나타냅니다.
2,3,5,6행이 일치하지 않는 것을 볼 수 있습니다. 이유와 정규 표현식의 어느 부분이 자격 박탈의 원인인지 알 수 있나요?
여기에 답이 있습니다
비밀번호 제약
정규식을 사용하여 제약 조건을 적용할 수도 있습니다. 여기서 우리는 긍정적인 예측의 힘을 발견할 것입니다.
문자열에 숫자가 있는 경우에만 문자열을 받아들이고 싶다고 가정해 보겠습니다. 당신은 이미 '\d' 클래스를 사용하여 숫자를 찾는 방법을 알고 있습니다. 이를 달성하기 위해 [^\d]*\d을 사용할 수 있습니다. . 이는 숫자가 아닌 문자와 0회 이상 일치한 다음 숫자와 일치합니다.
.*\d 표현식을 사용할 수도 있습니다. 한 자리 숫자와 일치하도록 합니다. 따라서 문자열에 숫자가 없으면 예측이 실패하고 해당 문자열의 어떤 문자도 일치하지 않아 빈 문자열 ""이 반환됩니다.
프로그래밍 언어를 사용할 때 정규 표현식이 빈 문자열을 반환했는지 확인하고 제약 조건이 충족되지 않았는지 확인할 수 있습니다.
우리는 다음 기준을 적용하는 정규식을 만들 것입니다:
- 최소 8자, 최대 16자
- 소문자가 하나 이상 있어야 합니다.
- 최소 하나의 대문자.
- 적어도 하나의 숫자입니다.
이를 달성하기 위해 긍정적인 예측을 사용할 수 있습니다. 정규식은 다음과 같습니다:
^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,16}$
아래 표에서는 정규식의 어느 부분이 어떤 제약 조건을 부과하는지 설명합니다.
패턴 부과 제약.{8,16} 최소 8~최대 16자(?=.*[a-z]) 최소 1개의 소문자(?=.*[A-Z]) 최소 하나의 대문자(?=.*\d) 최소 한 자리
최소 5개의 대문자를 적용하려면 어떤 수정이 필요합니까?
(?=.*[A-Z]{5,})이라고 생각할 수도 있습니다. 일을 할 것입니다. 하지만 이 표현은 5글자가 모두 모여야 합니다. rand-ABCDE-rand와 같은 문자열 일치하지만 0AxBCDxE0 대문자가 5개 있어도(인접하지 않기 때문에) 일치하지 않습니다.
하지만 이번에도 우리는 구조하러 오는 포획 그룹이 있습니다. 우리는 문자열의 어느 위치에서나 5개의 대문자를 일치시키고 싶습니다. 우리는 .*[A-Z]에 대문자 1개를 일치시킬 수 있다는 것을 이미 알고 있습니다. . 이제 이를 캡처 그룹에 넣고 최소 5의 수량자를 첨부합니다. 표현식은 (.*[A-Z]){5,}입니다. .
최종 답변은 다음과 같습니다:
(?=.*[A-Z]) 대신 (?=(.*[A-Z]){5,})이 필요합니다 . 표현식은 ^(?=.*[a-z])(?=(.*[A-Z]){5,})(?=.*\d).{8,16}$가 됩니다. .
더 강력한 비밀번호를 적용하기 위해 비밀번호에 특정 단어가 포함되지 않도록 요구할 수도 있습니다.
예를 들어 pass이 포함된 경우 비밀번호를 거부하려고 합니다. 또는 1234 . 부정적인 예측은 이 작업을 위한 도구입니다. 정규식은 ^(?!.*(pass|1234)).*$입니다. .
이 정규식에서는 pass을 입력합니다. 및 1234 캡처 그룹 내에서 논리 OR 연산자를 사용했습니다. 이 캡처 그룹은 ?!.* 접두사가 붙은 다른 캡처 그룹 내에 중첩되어 있습니다. . 이렇게 하면 .{8,}에 의해 최소 8자가 있는 경우 일치하는 부정 예측이 됩니다. pass 조건으로 또는 1234 문자열 어디에도 존재할 수 없습니다.
마지막 한마디
이 글을 읽으면서 많은 연습을 하시길 바랍니다. 일부 구문을 잊어버리더라도 괜찮습니다. 중요한 것은 핵심 개념을 이해하고 정규식으로 무엇이 가능한지 잘 아는 것입니다. 그런 다음 패턴을 잊어버린 경우 Google에 검색하거나 치트시트를 참조하면 됩니다.
더 많이 연습할수록 외부의 도움 없이도 더 많은 것을 얻을 수 있습니다. 결국에는 매우 복잡하고 효과적인 정규식을 완전히 오프라인으로 작성할 수 있게 됩니다.
이미 좋은 정규식 치트시트가 있으므로 여기서 핵심 개념과 일반적인 사용 사례에 대해 참조할 수 있는 좀 더 심층적인 내용을 만들고 싶었습니다.
치트시트를 찾고 있다면 QuickRef의 치트시트가 도움이 될 것입니다. 구문을 기억하기에 좋은 곳이며 다양한 프로그래밍 언어의 정규식 관련 함수에 대한 기본 개요도 제공합니다.
대부분의 정규식 기술은 모든 프로그래밍 언어 및 도구에서 동일하지만 특정 도구는 추가 기능을 제공할 수 있습니다. 따라서 귀하에게 가장 적합한 도구를 선택하려면 사용 중인 도구에 대해 조사해 보세요.
내 마지막 제안은 가능하다고 해서 정규식을 강제로 사용하지 않는 것입니다. 대부분의 경우 일반 string.find() 일을 끝내기에 충분합니다. 하지만 터미널에 거주한다면 확실히 정규 표현식만으로 많은 일을 할 수 있습니다.
이런 유형의 기사가 마음에 드신다면 제 블로그나 트위터를 계속 지켜봐 주시기 바랍니다.
무료로 코딩을 배우세요. freeCodeCamp의 오픈 소스 커리큘럼은 40,000명 이상의 사람들이 개발자로 취업하는 데 도움을 주었습니다. 시작하세요