본문 바로가기

프로그래밍(TA, AA)/스크립트

[스크립트] 정규표현식 알아보기 (1)

정규표현식에 대해 알아보기 전에, 정규표현식으로 할 수 있는 일을 나열했다.

 

정규표현식 기본 기능 나열

  1. 리터럴 텍스트에 일치
  2. 비인쇄 문자에 일치
  3. 여러 문자 중 하나와 일치
  4. 모든 문자와 일치
  5. 행 시작이나 끝의 대상을 대조
  6.  단어 채로 대조
  7. 유니코드 번호, 속성, 블록, 스크립트
  8. 다자택일 대조
  9. 여러 일치부를 그룹으로 묶어 캡처
  10. 앞서 일치된 텍스트를 다시 대조
  11. 각 일치부를 캡처하고 명명하기
  12. 정규식의 일부분을 특정 횟수로 반복하기
  13. 최소 반복 vs 최대 반복
  14. 불필요한 역행 제거
  15. 지나친 반복 방지
  16. 한 일치부를 전체 일치부에 넣지 않고 검사
  17. 조건문으로 두 후보 중 하나 대조
  18. 정규식에 주석 추가
  19. 치환 텍스트에 리터럴 텍스트 삽입
  20. 치환 텍스트에 정규식 일치부 삽입
  21. 치환 텍스트에 정규식 일치부의 일부만 삽입
  22. 치환 텍스트에 일치 콘텍스트 삽입

 

정규표현식 프로그래밍

  1. 프로그래밍 언어와 정규식 스타일
  2. 소스코드 안의 리터럴 정규식
  3. 정규식 라이브러리 불러오기
  4. 정규식 객체 생성
  5. 정규식 옵션 지정
  6. 대상 문자열과 일치되는지 검사
  7. 대상 문자열과 완전히 일치되는지 검사
  8. 일치 텍스트 가져오기
  9. 일치부 지점과 길이 알아내기
  10. 일치 텍스트의 일부분 가져오기
  11. 모든 일치부 가져오기
  12. 모든 일치부 반복
  13. 절차 코드 안의 일치부 유효검사
  14. 일치부를 다른 일치부 안에서 검색
  15. 모든 일치부 치환
  16. 절차 코드 안의 일치부 유효검사
  17. 일치부를 다른 일치부 안에서 검색
  18. 모든 일치부 치환
  19. 일부분을 재사용해서 일치부 치환
  20. 일치부를 코드 안에 생성된 텍스트로 치환
  21. 모든 일치부를 다른 정규식의 일치부로 치환
  22. 모든 일치부를 다른 정규식 일치부들 사이 일치부로 치환
  23. 문자열 분리
  24. 정규식 일치부만 남기고 문자열 분리
  25. 행 단위 검색

단어, 행, 특수문자 정규표현식

  1. 특정 단어 검색
  2. 여러 단어 중 하나 검색
  3. 비슷한 단어 검색
  4. 특정 단어를 제외한 모든 단어 검색
  5. 뒤에 특정 단어가 없는 단어 검색
  6. 앞에 특정 단어가 없는 단어 검색
  7. 근접 단어 검색
  8. 중복 단어 검색
  9. 중복 행 제거
  10. 특정 단어가 있는 완전한 행 대조
  11. 특정 단어가 없는 완전한 행 대조
  12. 문자열의 시작과 끝 공백 제거
  13. 연이은 공백을 빈칸 한 개로 치환
  14. 정규식 메타문자 이스케이프 처리

숫자 정규표현식

  1. 정수
  2. 16진수
  3. 2진수
  4. 리딩 제로 제거
  5. 특정 범위 내의 정수
  6. 특정 범위 내의 16진수
  7. 부동소수점 수
  8. 천 단위 구분기호가 있는 숫자
  9. 로마 숫자

정규표현식이란? 애플리케이션과 프로그래밍 언어에서 사용할 수 있는 특수한 텍스트 패턴이다. 능숙하게 정규표현식을 사용하면, 프로그램 작성과 텍스트 처리를 간소화할 수 있게 된다.

 

정규식 스타일들은 프로그래밍 언어와 일대일 대응되진 않는다. 스크립트 언어에는 대체로 고유의 내장 정규식 스타일이 들어있다. 그렇지 않은 프로그래밍 언어는 정규식을 지원하는 라이브러리를 이용한다. 일부 라이브러리는 다국어를 지원하지만, 특정 언어는 그 언어를 지원하는 다른 라이브러리가 필요할 수도 있다.

 

오늘날 가장 흔히 쓰이는 정규식 스타일들은 모두 Perl 스타일의 정규식 계통이다. 일부 스타일에는 다른 스타일보다 기능이 더 많이 들어있다. 그러나 만약 두 스타일의 기능이 같다면 그 둘은 같은 문법을 사용할때가 많다.

 

버그를 교정하면 코너 케이스가 변하지만, 정규 스타일은 과거에 에러로 처리된 구문에 새 의미가 부가되어 기능이 늘어나는 것 말고는 웬만해선 바뀌지 않는다.

코너 케이스: 정상 조작 요인들의 범위 밖에서만 발생하는 문제나 상황, 특히 각 요인이 자체에 지정된 범위 내에 있더라도 여러 환경 변수나 조건들이 일제히 극단 레벨(최대나 최소)에 있으면 드러나게 되는 문제나 상황을 말한다. 일례로 스피커 사운드가 왜곡될 수 있지만 이는 최대 음량, 최대 베이스, 고습도 환경이라는 모든 요인의 극단적 조건에서 재생될 경우에 한해서만 그렇다. 이러한 코너 케이스와 달리 단일한 조작 요인의 최대/최소 조건에서만 발생하는 문제를 엣지 케이스(edge case)라고 한다.

 

 

Perl

오늘날 정규색이 대중화될 수 있었던 데에는 Perl에 내장된 정규식 기능의 역할이 크다. Perl이나 Perl 호환 정규식 사용을 필요로 하는 많은 애플리케이션과 정규식 라이브러리들이 사실상 Perl 스타일 정규식을 사용한다. PCRE는 'Perl 호환 정규식' C언어 라이브러리로, 사실상 PCRE는 Perl 스타일에 불과하다. 내부적으로 적용하는 정규식 스타일에 대해 구체적 표시가 없는 애플리케이션들 중 대부분은 내부적으로 PCRE 스타일의 정규식을 사용한다.

 

Java

java.util.regex 패키지 안에 정규식을 포함하는 java 정규식은 표준과 내장이라는 장점 외에도, Perl 스타일 정규식의 완벽한 기능을 제공하면서 C로 작성된 애플리케이션에 비해 성능이 뛰어나다. Java로 개발된 최근 소프트웨어가 내부적으로 사용하는 정규식 스타일은 Java 스타일일 가능성이 높다.

 

JavaScript

ECMA-262 표준 버전3에 정의되어 있는 정규식 스타일을 JavaScript라는 단어로 표기한다. 이 표준에는 ECMAScript 프로그래밍 언어가 정의돼 있는데, 이 언어는 각종 웹 브라우저에 들어있는 JavaScript와 JScript 코드를 통해 잘 알려져 있다. 그러나 모든 브라우저에는 표준에 어긋나게 만드는 각종 코너 케이스 버그가 존재한다.

 

사용자가 웹서버 응답을 대기하지 않고 정규식을 사용해 검색이나 필터링 할 수 있는 웹사이트라면, 그 사이트는 JavaScript 정규식 스타일을 사용하는 것이다. 왜냐하면 JavaScript 스타일만이 유일한 크로스 브라우저 클라이언트 측 정규식 스타일이기 때문이다.

 

Python

Python은 자체의 re 모듈을 통해 정규식을 지원한다. Python의 정규식 기능은 수년간 변함없이 유지돼 왔다.

 


검색치환 함수는 대상 문자열, 정규식, 치환 문자열을 받아서, 정규식의 모든 일치부를 치환 텍스트로 치환한 대상 문자열로 출력한다.

 

치환 텍스트는 비록 정규식이 아니지만 특정한 특수 문법을 사용하여 동적 치환 텍스트를 작성할 수 있다. 어느 정규식 스타일이든, 정규식과 일치된 텍스트나 캡처 그룹을 치환 텍스트 안에 재삽입할 수 있다.

 

콘텍스트란 정규식 대조가 적용되는 대상 텍스트, 즉, 피 대조 텍스트를 뜻한다. 일치부 앞의 텍스트를 좌 콘텍스트, 일치부 뒤의 텍스트를 우 콘텍스트라고 한다. 전체 콘텍스트는 좌 콘텍스트, 일치부, 우 콘텍스트로 구성된다.

 

정규식 소프트웨어 개발자마다 사고방식이 다르다보니 문법/기능이 다른 여러 정규식 스타일이 파생되었다. 그리고 정규식 스타일보다도 치환 텍스트 스타일의 수가 훨씬 많다. 정규식 엔진을 제작하기란 어렵다. 대부분의 프로그래머는 기존 것을 재사용하는 방법을 더욱 선호하므로, 기존 정규식 엔진에 검색치환 기능을 추가하는 것은 쉽다. 그 결과 내장 검색치환 기능이 없는 정규식 라이브러리들엔 수많은 치환 텍스트 스타일이 생겨났다.

 

모든 애플리케이션과 프로그래밍 언어는 자체적인 검색치환 기능을 제공해야 한다. 대부분의 프로그래머는 기존 문법을 복제하려고 하지만 정확히 똑같이 복제하진 않기 때문에 차이가 발생할 수 있다.

 

 

Perl

Perl에는 s/regex/replace/ 연산자를 통한 정규식 치환 기능이 내장돼 있다. Perl 치환 텍스트 스타일은 Perl 정규식 스타일과 일치한다.

 

PHP

PHP 치환 텍스트 스타일은 PHP의 preg_replace 함수를 의미한다. 이 함수는 PCRE 정규식 스타일과 PHP 치환 텍스트 스타일을 사용한다. PCRE를 사용하는 다른 프로그래밍 언어들은 PHP와는 다른 치환 텍스트 스타일을 사용한다. PCRE를 사용하는 다른 프로그래밍 언어들은 PHP와는 다른 치환 텍스트 스타일을 사용한다. 

 

Java

java.util.regex 패키지에는 내장 검색치환 함수들이 들어있다.

 

JavaScript

ECMA-262 표준 Edition 3에 정의되어 있는 치환 텍스트 스타일과 정규식 스타일을 확인한다.

 

Python

Python의 re 모듈에는 검색치환 기능의 하위 함수가 들어있다. Python 치환 텍스트 스타일은 Python 정규식 스타일과 일치한다. Python의 정규식 기능은 수년에 걸쳐 안정화 되었다.

 

리터럴 정규식을 문자열처럼 따옴표로 묶으면 문자열 이스케이프 규칙이 정규식 이스케이프 규칙보다 복잡하기 때문에 판독이 훨씬 어려워진다. 정규식 기본을 이해한 뒤에 이스케이프에 대해 살펴보는것을 권장한다.

 


정규표현식 작성 무료 툴

 

RegexPal (http://regexpal.com)

Enter regex here라는 문구가 적혀있는 박스안에 정규식을 입력한다. 그뒤에 RegexPal은 사용자가 입력한 정규식에 자동으로 구문 채색을 적용하므로, 정규식 안에 문법 에러를 한 눈에 볼 수 있다.

 

myregexp.com (http://www.myregexp.com)

Java 개발자를 위한 정규식 테스터이다. 정규식은 Regular Expression 박스에 입력하면 되고, Flags 메뉴에서 필요한 정규식 옵션을 지정하면 된다. 

Java 코드 안에 이미 문자열로 들어있는 정규식을 테스트하려면, 클립보드로 전체 문자열을 복사한다. myregexp.com 테스터로 와서 Edit 메뉴에 들어있는 Paste Regex from Java String을 클릭한다. 정규식 편집이 끝났으면 Edit 메뉴에서 Copy Regex for Java Source를 클릭한다. Edit 메뉴에는 이와 유사한 JavaScript와 XML용 명령들도 있다.

 

정규식 밑에는 각기 다른 테스트를 할 수 있는 4개의 탭이 존재한다.

Find: 샘플 텍스트 안의 정규식 일치부를 전부 강조한다. 이 부분들은 Java의 Matcher.find() 메서드에 의해 검색된 것이다.
Match: 정규식이 샘플 텍스트와 전체적으로 일치하는지 여부를 검색한다. 만일 그렇다면 전체 텍스트가 강조된다. 이는 String.matches()와 Matcher.matches() 메서드에 의해 이루어진다.
Split: 우측에 있는 박스엔 정규식과 샘플 텍스트 내용을 수정할때마다 String.split()이나 Pattern.split()에 의해 반환된 문자열들의 배열이 표시된다.
Replace: 치환 텍스트를 입력하면 String.replaceAll()이나 Matcher.replaceAll()에 의해 반환된 텍스트가 우측 박스에 표시된다.

myregexp.com은 Eclipse용 플러그인과 IntelliJ IDEA용 플러그인을 제공한다.

 

reAnimator (http://osteele.com/tools/reanimator)

정규식 엔진이 정규식 검색 수행에 사용하는 유한 상태 머신을 그래픽 표현물로 보여주는 툴이다. reAnimator의 정규식 문법은 아주 제한적이다. 

 

먼저 페이지 상단의 Pattern 박스로 가서 edit 버튼을 누른다. 입력 필드가 생기면 거기에 정규식을 입력하고 Set을 클릭한다. 그 다음 Input 필드에 대상 텍스트를 천천히 입력한다.

 

한 글자씩 입력할때마다 하단 그림의 색상 공이 현재까지의 사용자 입력 내용을 바탕으로 상태 머신 경로를 따라 이동하면서 상태 머신 내에서의 도착 지점을 보여준다. 파란색 공은 상태 머신이 입력을 받아들였으나 완전한 일치를 위해서는 추가 입력이 필요함을 나타내며, 연두색 공은 입력 내용이 전체 패턴과 일치함을 나타낸다. 아무 공도 표시되지 않으면 상태 머신에서 입력 내용과 일치하지 않음을 의미한다.

 

reAnimator는 마치 ^와 $ 앵커 사이에 넣었을 때처럼 정규식이 전체 입력 문자열과 일치할때만 일치부를 표시한다. 이는 수학적 개념에 한정된 표현식의 또 한가지 속성이다. 

 


grep이라는 이름은 Unix 텍스트 에디터인 ed에서 정규식 검색을 수행했던 g/re/p 명령에서 유래됐다. ed는 정규식을 지원한 최초 애플리케이션 중 하나였다. ed는 정규식을 지원한 최초 애플리케이션 중 하나였다. 이 명령은 현재 모든 Unix 시스템에 정규식을 사용해서 파일들을 검색할 수 있는전용 grep 유틸리티가 존재할 정도로 대중적으로 사용되었다. 터미널 창에 'man grep'을 입력하면 출력되는 모든 설명을 볼 수 있다.

 

텍스트 에디터에는 최소한의 기본적인 정규식 기능이 들어있다. 일반적으로 검색이나 검색치환 패널에 정규식 모드를 활성화할 수 있는 체크박스가 있다. EditPad Pro 같은 일부 에디터는 구문 채색이나 클래스/함수 목록 같은 각종 텍스트 처리 기능들에도 정규식을 사용한다. 각 텍스트 에디터에 들어있는 문서에 이러한 기능들이 전부 설명돼 있다.

 

Boxer Text Editor(PCRE), Dreamweaver(JavaScript), EditPad Pro, Multi-Edit(PCRE), NoteTab(PCRE), UltraEdit(PCRE), TextMate, EditPlus

 


리터럴 텍스트에 일치시키는 것 자체는 목적이 아닌 수단이다. 리터럴 텍스트를 검색하는 것만이 목적이라면 정규식을 사용할 필요가 없기 때문이다. 정규식을 작성하는 도중에 특정 텍스트에 글자 그대로 일치되게 해야할때도 있기 때문에, 어느 문자들을 이스케이프 처리해야 하는지 알아두는것도 좋다.