정규식 팁
참고 ) 정규표현식은 표준인 POSIX의 정규표현식과 POSIX 정규표현식에서 확장된 Perl방식의 PCRE가 대표적이다. 여기서는 PCRE로 테스트함을 알려둔다.
오늘 있었던 정규식 관련 내용을 정리하려고 한다.
문제는 다음과 같다.
30008!30008!30007 => 참
30008!30007!30008 => 참
30007!30008!30008 => 참
30008!30007|30009 => 거짓
30007!30008!30008 => 참
30008!30008!30008 => 거짓
30007!30008 => 거짓
정규식으로 이걸 처리해야한다. 간단하게 설명하면 문자열에 30008 이 2개 이상 있고 30007도 1개 이상 있는경우만 참으로 되야한다.
기본적인 정규식을 생각해 봤더니 다음처럼 두개의 조건이 나온다.
조건 1 :
(.*30008.*){2,}
조건 2 :
(.*30007.*){1,}
OR
조건 1과 조건 2를 OR로 해보자. 30008이 두개 이상 있거나 30007이 1개 이상 있는경우
간단하게 | 로 붙이면 된다. |
(.*30008.*){2,}|(.*30007.*){1,}
AND
조건 1과 조건2가 동시에 만족을 해야한다고 해보자. 여기서 부터 조금 어렵다.
조건들이 매치가 된 이후 매치포지션이 0으로 다시 되돌아가서 처음부터 검색을 해야한다. 그래야 다음 조건이 글 처음부터 검색이 된다.
이걸 하기위해서는 lookaheads 연산자를 알아야한다. ?= 이걸로 표현된다.
각각의 조건들에 대해 다음처럼 하면된다.
(?=조건1)(?=조건2).*
내가 사용하는 조건에 넣으면
(?=(.*30008.*){2,})(?=(.*30007.*){1,}).*
이와 같다. 마지막에 .* 가 아주 중요하다. 없으면 아무것도 매치시키지 않을것입니다.
설명을 해보면 조건1로 검색을 다하고 매치포지션을 0으로 옮겨서 다시 검색 하고 두 조건에 맞고 그뒤에 .*(모든문자허용)가 있는걸 찾아라 라는것입니다.
잘 설명이 됬는지는 모르겠습니다.
생활 코딩 페북에서 답글로 도와주신 모든분들에게 고마움을 전합니다.
참고로 다음 사이트를 이용하시면 정규식 공부가 편합니다.
- https://regexr.com ==> 정규식을 바로 테스트할수 있어서 편합니다.
- https://regexper.com ==> 그림으로 보여줘서 이해가 편하더라구요
추가
?= 가 표준 정규식이 아니라는 이야기를 들었습니다. 찾아보니 다음과 같네요
정규표현식은 표준인 POSIX의 정규표현식과 POSIX 정규표현식에서 확장된 Perl방식의 PCRE가 대표적이다.
mysql
기본 정규식에 없어서 그런지 mysql에서는 위 정규식을 지원을 하지 않네요 .
일반적으로 다음처럼 사용하는데
select * from pet where species regexp 'do{}3' ;
내 정규식을 사용하면 에러가 난다.
select * from pet where species regexp '(?=(.*30008.*){2,})(?=(.*30007.*){1,}).*';
그래서 where절에 and를 사용하여 다음처럼 처리하였다. 1번 조건과 2번 조건을 and로 걸어서 사용했음.
select * from pet where species regexp '(.*30008.*){2,}' and species regexp '(.*30007.*){1,}';