MySQL 정규 표현식(Regexp)

⚡ 스마트 요약

MySQL 정규 표현식(REGEXP)은 와일드카드로 표현할 수 없는 다양한 패턴에 따라 열 값을 일치시킵니다. 이 문서에서는 REGEXP 구문, RLIKE 동의어, 지원되는 모든 메타 문자, myflixdb 데이터베이스에 대한 수정된 쿼리 예제, 그리고 새로 추가된 정규 표현식 함수에 대해 설명합니다. MySQL 8.0.

  • 🔍 핵심 Opera토르: REGEXP는 열을 패턴과 비교하여 일치하는 경우 1을 반환하는 반면, RLIKE는 REGEXP와 정확히 동일한 기능을 합니다.
  • 🧩 무늬 Anchors: 캐럿(^)은 일치 항목을 값의 시작 부분에 고정하고, 달러 기호($)는 일치 항목을 값의 끝 부분에 고정합니다.
  • 🔤 등장인물 목록: [abcd]는 괄호로 묶인 모든 문자와 일치하고, [^abcd]는 결과 집합에서 괄호로 묶인 모든 문자를 제외합니다.
  • ➕ 수량자: 별표, 더하기 기호, 물음표는 문자열 전체가 아닌 바로 앞에 있는 단일 문자에만 적용됩니다.
  • 🛡️ ESCAping 규칙 : 패턴 안에서 문자 그대로의 역슬래시는 두 번 반복되어야 합니다. 왜냐하면 MySQL 문자열을 두 번 처리합니다.
  • 🆕 버전 변경: MySQL 8.0 버전은 ICU 엔진으로 이동했고, [[:<:]] 및 [[:>:]]를 ​​\b로 대체했으며, REGEXP_LIKE, REGEXP_REPLACE, REGEXP_SUBSTR 및 REGEXP_INSTR을 추가했습니다.
  • ⚡ 성능 참고 사항: 정규 표현식(REGEXP)은 인덱스를 사용하지 않으므로, 쿼리에서 인덱스 조건을 사용할 수 있는 경우 먼저 해당 조건을 사용하여 행을 필터링하십시오.

무엇인가 MySQL 정규 표현식?

MySQL 정규식 복잡한 조건을 만족하는 데이터를 검색하는 데 도움이 됩니다. 정규 표현식은 찾고자 하는 값 자체가 아니라 값의 형태를 설명하는 패턴입니다.

이미 함께 일해본 경험이 있다면 MySQL 와일드 카드LIKE 연산자도 비슷한 결과를 내는데 왜 정규 표현식을 배워야 하는지 궁금할 수 있습니다. 그 이유는 바로 표현력 때문입니다. 와일드카드는 두 개의 기호만 사용할 수 있는 반면, 정규 표현식은 하나의 패턴으로 문자 범위, 대체 문자, 반복, 단어 위치까지 표현할 수 있습니다.

목적이 명확해졌으므로 다음 섹션에서는 모든 정규 표현식 쿼리에서 사용할 구문을 소개합니다.

정규 표현식의 기본 구문

정규 표현식의 기본 구문은 다음과 같습니다.

SELECT * FROM table_name
WHERE fieldname REGEXP 'pattern';

여기 :

  • “SELECT 문” 표준입니다 SELECT 문.
  • “WHERE 필드 이름” 는 정규 표현식이 실행되는 열의 이름입니다.
  • “REGEXP '패턴'” — REGEXP는 정규 표현식 연산자이고, 'pattern'은 일치시킬 패턴을 나타냅니다. RLIKE 하는 REGEXP의 동의어 그리고 동일한 결과를 반환합니다. LIKE 연산자와 혼동을 피하려면 REGEXP를 사용하는 것이 좋습니다.

이제 실제 사례를 살펴보겠습니다.

SELECT * FROM `movies`
WHERE `title` REGEXP 'code';

위 쿼리는 "code"라는 단어를 포함하는 모든 영화 제목을 검색합니다. "code"가 제목의 시작, 중간 또는 끝에 나타나는지는 중요하지 않습니다. 제목에 해당 패턴이 포함되어 있으면 해당 행이 반환됩니다.

값의 시작 부분을 문자 목록과 일치시키기

제목이 a, b, c 또는 d로 시작하고 그 뒤에 임의의 문자가 오는 영화를 찾고 싶다고 가정해 봅시다. 이 결과를 얻으려면 문자 목록과 캐럿 메타문자를 결합하면 됩니다.

SELECT * FROM `movies`
WHERE `title` REGEXP '^[abcd]';

위 스크립트를 실행하면 MySQL 워크 벤치 myflixdb 데이터베이스를 대상으로 검색한 결과는 다음과 같습니다.

영화_ID 제목 이사 연도_출시 카테고리_ID
4 Code 이름 블랙 에드가 짐즈 2010 NULL
5 아빠의 어린 소녀들 NULL 2007 8
6 천사와 악마 NULL 2007 6
7 다 빈치 Code NULL 2007 6

패턴 '^[abcd]'에서 캐럿(^)은 일치 항목이 값의 시작 부분에서 시작되어야 함을 의미하며, 문자 목록 [abcd]는 첫 글자가 a, b, c 또는 d인 제목만 허용합니다. 기본 정렬에서는 대소문자를 구분하지 않으므로 "Code "이름 Black"이 반환됩니다.

부정 문자 목록을 가진 문자를 제외합니다.

이제 스크립트를 수정하여 문자 목록을 반전시켜 어떤 행이 반환되는지 확인해 보겠습니다.

SELECT * FROM `movies`
WHERE `title` REGEXP '^[^abcd]';

위 스크립트를 실행하면 MySQL Workbench를 사용하여 myflixdb 데이터베이스를 실행한 결과는 다음과 같습니다.

영화_ID 제목 이사 연도_출시 카테고리_ID
1 캐리비안의 해적 4 롭 마샬 2011 1
2 사라 마샬을 잊어버림 니콜라스 스톨 러 2008 2
3 엑스 맨 2008
9 Honey moon 존 슐츠 2005 8
16 67% 유죄 2012
17 위대한 독재자 찰리 채플리 1920 7
18 샘플 영화 익명 8
19 영화 3 존 브라운 1920 8

문자 목록 내부에서 캐럿(^)의 의미가 바뀝니다. '^[^abcd]'는 여전히 일치 항목을 시작 부분에 고정하지만, [^abcd]는 이제 괄호로 묶인 문자 중 하나로 시작하는 모든 제목을 제외합니다.

이 두 예제는 앵커와 문자 목록만 사용합니다. 다음 섹션에서는 전체 메타 문자 집합에 대해 다룹니다.

정규식 메타문자

위 예시는 가장 간단한 형태의 정규 표현식을 보여줍니다. 메타문자를 사용하면 패턴 검색을 더욱 세밀하게 조정할 수 있습니다. 메타문자는 반복, 대안, 범위 및 위치를 표현하는 데 사용됩니다. 아래 표는 지원되는 모든 메타문자를 나열합니다. MySQL 정규 표현식 연산자와 각 연산자에 대한 수정된 예시입니다.

숯 기술설명 예시
* The 별표 (*) 0개 이상의 인스턴스와 일치합니다. 단일 문자 그것보다 앞선다. SELECT * FROM 영화 WHERE 제목 REGEXP 'da*'; "d" 뒤에 0개 이상의 "a" 문자가 오는 경우와 일치하므로 Da Vinci는 Code 그리고 Daddy's Little Girls도 해당됩니다. 문자 "a"가 반드시 있어야 할 경우에는 'da+'를 사용하세요.
+ The 더하기 (+) 앞에 오는 문자가 하나 이상 나타나는 경우와 일치합니다. SELECT * FROM `movies` WHERE `title` REGEXP 'mon+'; "mon" 뒤에 하나 이상의 "n" 문자가 포함된 모든 영화를 보여줍니다. 예를 들어, Angels and Demons입니다.
? The 물음표 (?) 앞에 오는 문자가 0개 또는 1개 나타나는 경우와 일치합니다. SELECT * FROM `카테고리` WHERE `카테고리_이름` REGEXP 'com?'; "co"에 선택적으로 "m"이 붙은 경우를 말합니다. 예를 들어, comedy와 romantic comedy가 있습니다.
. The 점(.) 줄바꿈을 제외한 모든 문자와 일치합니다. SELECT * FROM 영화 WHERE `출시 연도` REGEXP '200.'; "200"으로 시작하고 그 뒤에 임의의 문자 하나가 오는 해에 개봉된 모든 영화를 보여줍니다. 예를 들어, 2005, 2007, 2008과 같습니다.
[알파벳] The 문자 목록 [abc] 괄호 안의 문자 중 하나와 일치합니다. SELECT * FROM `movies` WHERE `title` REGEXP '[vwxyz]'; "vwxyz"에 나오는 캐릭터가 하나라도 포함된 모든 영화를 보여줍니다. 예를 들어, 엑스맨과 다빈치 등이 있습니다. Code.
[^ abc] The 부정 목록 [^abc] 괄호로 묶인 문자를 제외한 모든 문자와 일치합니다. SELECT * FROM `영화` WHERE `제목` REGEXP '^[^vwxyz]'; 제목이 "vwxyz" 문자로 시작하지 않는 모든 영화를 보여줍니다.
[AZ] The 범위 [AZ] 모든 대문자와 일치합니다. SELECT * FROM `members` WHERE `postal_address` REGEXP '[AZ]'; 우편 주소에 A부터 Z 사이의 문자가 포함된 모든 회원에게 정보를 제공합니다. 예를 들어, 회원 번호 1번인 Janet Jones와 같습니다.
[az] The 범위 [az] 소문자와 일치합니다. SELECT * FROM `members` WHERE `postal_address` REGEXP '[az]'; 우편 주소에 a부터 z 사이의 문자가 포함된 모든 회원을 반환합니다. 기본 정렬 방식은 대소문자를 구분하지 않으므로 이 범위에는 대문자도 포함됩니다.
[0-9] The 범위 [0-9] 0부터 9까지의 숫자 중 하나와 일치합니다. `members` 테이블에서 `contact_number`가 정규 표현식 '[0-9]'인 경우를 선택합니다. 연락처에 숫자가 하나 이상 포함된 모든 회원을 보여줍니다. 예를 들어, Robert Phil.
^ The 캐럿(^) 해당 값을 시작 부분에 고정합니다. SELECT * FROM `movies` WHERE `title` REGEXP '^[cd]'; 제목이 "c" 또는 "d"로 시작하는 모든 영화를 보여줍니다. 예를 들어, Code 네임 블랙, 대디스 리틀 걸스, 그리고 다빈치 Code.
$ The 달러 기호 ($) 해당 값을 끝부분에 고정합니다. `movies` 테이블에서 `title`이 정규 표현식 'code$'인 경우를 선택합니다. 제목이 "code"로 끝나는 모든 영화를 보여줍니다. 예를 들어, 다빈치 Code.
| The 세로 막대(|) 대안들을 분리해냅니다. SELECT * FROM `영화` WHERE `제목` REGEXP '^[cd]|^[u]'; 제목이 "c", "d" 또는 "u"로 시작하는 모든 영화를 보여줍니다. 예를 들면, Code 이름 블랙, 다빈치 Code그리고 언더월드 – AwakenING.
\b The 단어 경계(\b) 단어의 시작이나 끝과 일치합니다. 기존의 [[:<:]] 및 [[:>:]] 마커를 대체합니다. MySQL 8.0 버전이 삭제되었습니다. `movies` 테이블에서 `title`이 정규 표현식 '\\bfor'인 경우를 선택합니다. "for"로 시작하는 단어가 포함된 모든 영화를 보여줍니다. 예를 들어, Forgetting Sarah Marshal처럼요. MySQL 5.7 해당 패턴은 '[[:<:]]for'입니다.
[[:수업:]] The 캐릭터 클래스 지정된 문자 그룹과 일치합니다. [[:alpha:]]는 알파벳, [[:space:]]는 공백, [[:punct:]]는 구두점, [[:upper:]]는 대문자를 나타냅니다. 더블 대괄호. `movies` 테이블에서 `title`이 정규 표현식 '^[[:alpha:][:space:]]+$'인 경우를 선택합니다. 제목에 문자와 공백만 포함된 모든 영화를 표시합니다. 예를 들어, Forgetting Sarah Marshal이 표시되지만, Pirates of the Caribean 4는 숫자 때문에 제외됩니다.

백슬래시(\)는 이스케이프 문자입니다. 왜냐하면 MySQL 먼저 문자열을 파싱하고 그 다음 패턴을 파싱합니다. 리터럴 백슬래시는 정규 표현식 패턴 내에서 이중 백슬래시(\\)로 작성해야 합니다.

⚠️ 버전 경고: MySQL 8.0.4 버전에서는 기존 정규 표현식 엔진이 ICU 라이브러리로 교체되었습니다. 이 버전에서 단어 마커 [[:<:]] 및 [[:>:]]가 제거되었으므로 이전 버전에서 복사한 패턴은 "구문 오류"와 함께 실패합니다. MySQL 8.0. 대신 \b를 사용하십시오.

이제 모든 메타 문자가 정의되었으므로 다음과 같은 질문이 제기됩니다. 언제 REGEXP가 더 간단한 LIKE 연산자를 대체해야 할까요?

정규 표현식과 유사도 표현식 중 어떤 것을 사용해야 할까요?

두 연산자 모두 패턴으로 행을 필터링하지만, 해결하는 문제가 다릅니다. LIKE 연산자는 두 개의 기호만 인식하는 반면, REGEXP 연산자는 위에 표시된 전체 메타문자 집합을 인식합니다. 이러한 강력한 기능에는 단점이 따르므로, 어떤 연산자를 선택할지는 선호도라기보다는 장단점을 고려해야 합니다.

표준 LIKE REGEXP
패턴 기호 % 및 _만 Anchors, 범위, 교체, 수량자, 문자 클래스
일반적인 사용 접두사, 접미사 및 "포함" 검색 유효성 검사, 다중 대안, 위치 인식 매칭
인덱스 사용량 패턴이 %로 시작하지 않는 경우 가능합니다. 인덱스를 전혀 사용하지 않습니다.
반환 값 참 또는 거짓 피연산자 중 하나라도 NULL이면 1 또는 0을 반환하고, 두 피연산자 중 하나라도 NULL이면 NULL을 반환합니다.

단순 일치에는 LIKE 연산자를 선택하세요. 가독성이 좋고 인덱스를 활용할 수 있습니다. "c 또는 d로 시작하고 숫자로 끝나는" 것처럼 하나의 패턴으로 여러 규칙을 표현해야 할 때는 REGEXP 연산자를 선택하세요. 대규모 테이블의 경우, 먼저 인덱스 조건을 사용하여 원하는 행을 추려낸 다음, 그 축소된 행 집합에 REGEXP 연산자를 적용하세요.

MySQL 8.0 정규 표현식 함수

REGEXP 연산자는 단 하나의 질문에만 답합니다. 값이 패턴과 일치하는가? MySQL 8.0 버전에는 더욱 심화된 위치 파악 기능을 제공하는 네 가지 기능이 추가되었습니다.tract를 입력하고 일치하는 텍스트를 다시 작성합니다. 각 함수는 선택적 match_type 인수를 허용하며, 'c'는 대소문자를 구분하는 비교를 강제하고 'i'는 대소문자를 구분하지 않는 비교를 강제합니다.

  • REGEXP_LIKE(expr, pattern) 값이 패턴과 일치하면 1을 반환합니다. 이는 정규 표현식 연산자의 함수 형태이며, match_type 인수를 통해 대소문자를 구분할 수 있습니다.
  • REGEXP_INSTR(expr, pattern) 일치하는 첫 번째 문자의 위치를 ​​반환하거나 패턴을 찾을 수 없는 경우 0을 반환합니다.
  • REGEXP_SUBSTR(expr, pattern) 일치하는 부분 문자열 자체를 반환하므로 긴 텍스트 값에서 연도, 코드 또는 숫자를 추출하는 데 유용합니다.
  • REGEXP_REPLACE(expr, pattern, replacement) 일치하는 모든 항목을 대체한 값을 반환하므로 내부 데이터를 정리할 수 있습니다. SQL UPDATE 쿼리.
SELECT title,
       REGEXP_SUBSTR(title, '[0-9]+') AS number_in_title
FROM `movies`
WHERE REGEXP_LIKE(title, '[0-9]');

위 쿼리는 숫자가 포함된 모든 영화 제목과 해당 숫자를 반환합니다. MySQL 5.7 이러한 기능은 사용할 수 없으므로 REGEXP 연산자가 유일한 옵션으로 남습니다.

자주 묻는 질문

기본적으로는 그렇지 않습니다. REGEXP는 열의 정렬 방식을 따르며, 표준 정렬 방식은 대소문자를 구분하지 않습니다. 대소문자를 구분하는 비교를 강제하려면 열 이름 앞에 BINARY 키워드를 추가하거나, REGEXP_LIKE 함수에 'c' 일치 유형을 지정하세요.

기능적인 차이는 없습니다. RLIKE는 REGEXP의 동의어입니다. MySQL 호환성을 위해 유지합니다. 실제로는 REGEXP가 선호되는데, RLIKE는 관련 없는 다른 것과 쉽게 혼동될 수 있기 때문입니다. 좋아요 연산자 와일드카드에 사용됩니다.

정규 표현식은 인덱스를 사용할 수 없으므로 MySQL 패턴을 행 단위로 평가합니다. 먼저 인덱싱 조건, 날짜 범위 또는 전체 텍스트 인덱스를 사용하여 스캔할 행 수를 줄인 다음, 더 작아진 결과 집합에 정규 표현식을 적용합니다.

예. AI 비서는 일반 언어 규칙을 정규 표현식 패턴으로 변환하고 각 메타 문자를 설명합니다. 결과를 테스트해 보세요. MySQL 워크 벤치 샘플 행에 대해 비교하는 이유는 앵커 하나가 잘못 배치되면 전체 결과 집합이 바뀌기 때문입니다.

네. AI 비서는 구두점을 제거하거나, 전화번호를 정규화하거나, 불필요한 공백을 제거하는 REGEXP_REPLACE 문을 생성합니다. 먼저 SELECT 문 안에서 해당 패턴을 실행하고, 변경된 값을 확인한 후에만 다른 문에 적용하세요. 업데이트 문.

이 게시물을 요약하면 다음과 같습니다.