기억하기보단 기록하자
정규 표현식 정리 본문
정규 표현식 만들기
정규식을 만드는 방법에는 두 가지가 있다.
정규식 리터럴(슬래쉬"/"로 감싸는 패턴)을 사용하는 방법은 다음과 같다.
var reg = /ab+c/;
정규식 리터럴은 스크립트가 불러와질 때 컴파일된다.
만약 정규식이 상수라면, 이렇게 사용하는 것이 성능을 향상할 수 있다.
RegExp 객체의 생성자 함수를 호출하는 방법도 있다.
var reg = new RegExp("ab+c");
생성자 함수를 사용하면 정규식이 실행 시점에 컴파일된다.
정규식의 패턴이 변경될 수 있는 경우, 혹은 사용자 입력과 같이 다른 출처로부터 패턴을 가져와야 하는 경우에는 생성자 함수를 사용하는 편이 좋다.
정규식 특수 문자 사용
특수 문자 | 의미 |
^ | 입력의 시작 부분에 해당하며 ^a 는 "abc" 의 'a' 에 해당된다. ^문자로 시작함을 의미한다. |
$ | 입력의 끝 부분에 해당하며 c$ 는 "abc" 의 'c' 에 해당된다. 문자$로 끝남을 의미한다. |
* | 표현식이 0회 이상 연속으로 반복되는 부분에 해당하며 {0,} 와 같은 의미이다. a*b 는 "aabc" 'aab' 에 해당된다. |
+ | 표현식이 1회 이상 연속으로 반복되는 부분에 해당하며 {1,} 와 같은 의미이다. * 와 달리 적어도 1개는 있어야 매치된다. |
? | 표현식이 0 또는 1회 등장하는 부분에 해당하며 {0,1} 와 같은 의미이다. 표현식이 있을 수도 있고, 없을 수도 있다. |
. | 개행 문자를 제외한 모든 단일 문자에 해당한다. |
(x) | 하나의 패턴구분자 안에 서브 패턴을 지정해서 사용할 경우 괄호로 묶어주는 방식을 사용한다.(그룹으로 묶는다) |
x|y | 'x' 또는 'y'에 해당한다. |
{n} | 앞 표현식이 n번 나타나는 부분에 해당된다. |
{n,m} | 앞 표현식이 최소 n개, 최대 m개가 나타나는 부분에 해당한다. m이 생략되면 m은 ∞에 해당된다. |
[xyz] | 문자 클래스이며 'x', 'y', 'z' 중에 하나를 의미한다. |
[^xyz] | 문자 클래스안에서의 '^' 는 not을 의미한다. 'x', 'y', 'z' 가 아닌 문자에 해당된다. |
[x-z] | 문자 클래스안에서의 '-'(하이픈)은 문자의 범위 지정에 해당된다. 'x' 부터 'z' 까지 문자 중에 하나의 문자에 해당된다. |
\b | 문자와 공백 사이를 의미한다. |
\B | 문자와 공백 사이가 아닌 것을 의미한다. |
\d | 숫자 문자에 해당한다. [0-9] 와 동일하다. |
\D | 숫자 문자가 아닌 문자에 해당된다. |
\s | 공백 문자에 해당된다. |
\S | 공백 문자가 아닌 문자에 해당된다. |
\w | '_'(밑줄 문자), 영문자, 숫자에 해당된다. [A-Za-z0-9_] 와 동일하다. |
\W | 단어 문자가 아닌 문자에 해당된다. [^A-Za-z0-9_] 와 동일하다. |
정규식 사용하기
메소드 | 설명 |
exec | 해당하는 문자열을 찾는 RegExp 메소드. 정보를 가지고 있는 배열을 반환. 해당하는 문자열를 찾지 못하면 null을 반환한다. |
test | 해당하는 문자열이 있는지 검사하는 RegExp 메소드. true 나 false 를 반환한다. |
match | 해당하는 문자열을 찾는 RegExp 메소드. 정보를 가지고 있는 배열을 반환. 해당하는 문자열을 찾지 못하면 null을 반환한다. |
search | 해당하는 문자열이 있는지 검사하는 String 메소드. 해당하는 부분의 인덱스를 반환한다. 해당하는 문자열을 찾지 못하면 -1을 반환한다. |
replace | 해당하는 문자열을 찾아 다른 문자열로 치환하는 String 메소드이다. |
split | 정규식 혹은 문자열로 대상 문자열을 나누어 배열로 반환하는 String 메소드이다. |
플래그를 사용한 고급검색
플래그 | 설명 |
g | 전역 검색 |
i | 대소문자 구분 없는 검색 |
m | 다중행(multi-line) 검색 |
정규식에 플래그를 포함시키려면, 다음과 같이 사용하면 된다.
var reg = /pattern/i;
var reg = new RegExp("pattern", "i");
"i" 부분에 사용할 플래그를 사용하면 된다.
예시
1. 태그에서 opacity 값 추출
다른 브라우저들은 불투명도를 숫자로 표시하는 반면, IE 8과 이전 버전에서는 다른 방식으로 표시한다.
filter:alpha(opacity=50);
<div id="opacity" style="opacity:0.5;filter:alpha(opacity=50);"></div>
<script>
function getOpacity(elem) {
var filter = elem.style.filter;
return filter ?
filter.indexOf('opacity=') >= 0 ?
(parseFloat(filter.match(/opacity=([^)]+/)[1]) / 100) + "" :
"" :
elem.style.opacity;
}
getOpacity(document.getElementById('opacity'));
</script>
style에 filter가 없으면 일반적으로 사용하는 opacity:0.5의 0.5 값을 가져오고,
IE 8 버전 혹은 이전 버전이라면 filter.match 부분이 삼항 연산자에 의해 실행될 것이다.
([^)]+) 정규식을 살펴보면 [^)] 부분은 )가 일치하지 않는 하나의 문자에 일치한다. 그래서 'opacity=5'까지이다.
다음 '+' 표현식 1회 이상으로 인해 'opacity=50'까지 해당한다. '50'다음 ')'가 ^)에 해당하지 않으므로 '+'는 '50'까지만 해당한다.
정규식 다음에 있는 '[1]'은 match에 대한 그룹에 해당한다. '()'에 해당하는 값이다.
[0] : 'opacity=50'
[1] : '50'
console.log()로 확인해 볼 수 있다.
역참조로 HTML 태그 내용 매치
var html = "<b class='hello'>Hello</b> <i>world!</i>";
var pattern = /<(\w+)([^>]*)>(.*?)<\/\1>/g;
var match = pattern.exec(html);
console.log(match[0]); // "<b class='hello'>Hello</b>"
console.log(match[1]); // "b"
console.log(match[2]); // "class='hello'
console.log(match[3]); // "Hello"
'<\/\1>' 부분에서 '\1'이 첫 번째 캡처를 참조한다는 뜻이다.
첫 번째 캡처면 '(\w+)'에 해당하고 캡처의 값은 'b'이다. 그러므로 '</b>'에 해당된다.
캡처를 참조하는 다른 방법도 있다.
$1, $2, $3 문법을 캡처의 수만큼 이용할 수 있다.
var test = "fontFamily".replace(/([A-Z])/g, "-$1").toLowerCase();
console.log(test) // "font-family"
교체할 문자열은 $1을 이용해서 첫 번째 캡처의 값(F)을 참조하고 있다. 이것은 매치되는 부분을 찾기 전에는 몰랐던 부분을 교체할 문자열에 지정할 수 있도록 해 준다.
캡처를 만들지 않고 그룹으로 묶기
var pattern = /((ES-)+)6/;
var es = "ES-ES-6".match(pattern);
console.log(es[0]); // "ES-ES-6"
console.log(es[1]); // "ES-ES-"
console.log(es[2]); // "ES-"
코드에서 의도하고자 하는 것은 'ES-ES-' 하나의 캡처로 만들고자 하는 것이다.
하지만 괄호를 두 개로 묶어서 결과와 같이 하나 이상의 캡처가 만들어진다.
이럴때 정규식 표현식 문법은 괄호로 묶은 부분이 캡처를 생성하지 않도록 여는 괄호 바로 뒤에 '?:'을 지정하는 표기법을 제공한다.
이것을 수동적인 하위 표현식(Passive Subexpression)이라고 한다.
var pattern = /((?:ES-)+)6/;
var es = "ES-ES-6".match(pattern);
console.log(es[0]); // "ES-ES-6"
console.log(es[1]); // "ES-ES-"
위와 같이 변경하면 내부에 있는 괄호는 수동적인 하위 표현식으로 변경되서 캡처를 생성하지 않고, 바깥에 있는 묶음만 캡처를 생성한다.
정규 표현식을 작성할 때 가능하다면, 캡처가 필요하지 않은 곳에는 캡처가 적용되지 않도록 해주는게 좋다.
정규 표현식을 처리하는 엔진은 캡처를 저장하고 반환하는데 드는 비용을 많이 덜 수 있기 때문이다.
예제 부분은 조금씩 추가할 예정이다.
[출처] http://developer.mozilla.org/ko/docs/Web/JavaScript/Guide/정규식