정규식의 그룹 패턴 중에 Look-around
라는 게 있는데, 특정 패턴의 앞/뒤로 만족하는 패턴이 있는 경우에만 해당 패턴을 만족시키는 케이스를 말한다. 예를 들어 apple(?=s)
는 apples
의 apple
만 매칭되고 apple
이나 appled
는 매칭되지 않도록 하는 것이다. 이를 활용하여 비밀번호 유효성 검사에 정규식을 활용할 수 있다. 예를 들어,
- 6자리 이상
- 1개 이상의 영어 대문자
- 1개 이상의 숫자
라는 조건을 만족해야 한다면 저 전진 검색 패턴을 활용하면 된다.
먼저 글자수를 검사하려면 문자열 패턴 앞에 (?=\w{6,}$)
을 주면 일단 6글자 이상되는 문자열인 조건을 만족해야 매칭을 시도한다. 따라서 문자열이 6글자 이상인지를 보려면
^(?=\w{6,}$).*
와 같은 패턴을 사용한다. 그리고 이어서 영어 대문자나 숫자는 같은 방법을 쓰는데,
(?=.*?\d)
를 보자. .*
는 모든 글자를 의미한다. 이 패턴은 매우 욕심이 많아서 가능한 큰 영역을 잡으려고 한다. 이 때 .*\d
가 되면 저 패턴이 매치되기 시작하는 시점부터 마지막 숫자까지를 캡쳐할 것이다. 하지만 *
뒤에 ?
가 붙으면 반대로 욕심이 줄어들고 게을러지면서 최소한으로 패턴을 잡는다. 따라서 위 패턴은 숫자가 나올때까지 전체를 의미하고 이는 결국 이 전진검색 패턴뒤에 숫자가 나온다 (즉 1개 이상의 숫자가 있다)는 조건을 만족 시킨다.
즉, 패스워드가 위 조건을 만족하는지 정규식으로 한 방에 검사하려면
pwd.match(/^(?=\w{6,}$)(?=.*\d)(?=.*[A-Z]).*/)
을 검사하여 null
인지 여부를 확인하면 된다.
아래는 mithril을 사용하여 실시간으로 이를 체크하도록 한 예제이다.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!doctype html> | |
<script src="./lib/mithril.min.js"></script> | |
<script src="./js/password.js"></script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var password = {}; | |
password.controller = function() { | |
this.description = m.prop(""); | |
this.validate = function() { | |
var t = this.description(); | |
var s = t.match(/^(?=\w{6,}$)(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9]).*/); | |
if (s) { | |
return true; | |
} | |
return false; | |
} | |
} | |
password.view = function(ctrl) { | |
return m('html', [m('body', [m('div', [ | |
m('input[type=text]', { | |
onkeyup: m.withAttr('value', ctrl.description), | |
value: ctrl.description(), | |
style: { | |
backgroundColor: ctrl.validate() ? "green" : "red" | |
} | |
}), | |
m('input[type=text]', { | |
readonly: true, | |
value: ctrl.validate() ? "Pass!" : "Fail!", | |
style: { | |
color: ctrl.validate() ? "black" : "red", | |
} | |
}) | |
])])]); | |
} | |
m.module(document, password) |
참고로 자바스크립트는 후방검색(look-behind)은 지원하지 않는다.