백슬래시\ 는 특수 문자를 이스케이프하거나 특정 문자 클래스에 속하는 문자를 표현하는 데 사용된다
아래의 특수문자들을 정규검색으로 찾고 싶다면 \를 앞에 붙여서 이스케이프 처리를 해야한다
| 특수 문자 | 의미 |
|---|---|
| . | 개행 문자를 제외한 모든 단일 문자 |
| * | 0회 이상 반복 |
| + | 1회 이상 반복 |
| ? | 0 or 1회 반복 |
| | | or |
| () | 캡쳐 그룹 정의 |
| [] | 문자 클래스 정의 |
| {} | 횟수 or 범위 지정 |
| ^ | 문자열의 시작 |
| $ | 문자열의 끝 |
\ | 백슬래시는 \\로 사용한다 |
| 문자 클래스 | 의미 | 동일한 정규식 |
|---|---|---|
\d | 모든 숫자와 일치 | [0-9] |
\D | 숫자가 아닌 모든 문자와 일치 | [^0-9] |
\w | 모든 단어 문자(알파벳, 숫자 및 밑줄)와 일치 | [a-zA-Z0-9_] |
\W | 단어 문자가 아닌 모든 문자와 일치 | [^a-zA-Z0-9_] |
\s | 모든 공백 문자(스페이스, 탭, 줄바꿈 등)와 일치 | |
\S | 공백 문자가 아닌 모든 문자와 일치 | |
\b | 단어 경계를 의미. 단어 문자와 비단어 문자 사이의 위치와 일치 | |
\B | 단어 경계가 아닌 위치와 일치 |
조합하면 아래와 같이 사용할 수 있다
| 정규표현식 | 의미 |
|---|---|
\s+ | 하나 이상의 공백 문자 |
\d? | 숫자가 없거나 한자리 수 |
| [^abc] | a,b,c를 제외한 모든 문자와 일치 |
| [abc] | a,b,c가 들어간 모든 문자와 일치 |
\s{3} | 공백 3칸 |
\d{2,} | 2자리 이상 숫자 |
\w{1,4} | 1~4자 문자 |
(?=...)형식을 사용하며 ...에 찾고자 하는 패턴을 넣는다
Reg(?=Ex)
뒤에 Ex가 붙는 Reg를 찾는다. -> RegEx
^(?=.*\d).{8,}$
.* 어떤 문자가 0번 이상
.*\d 어떤 문자 0번 이상 + 숫자 1자리
^, $ 이 패턴으로 시작해서 끝나는 문자
.{8,} 모든 문자 8자리 이상
(?=.*\d) 문자열 어딘가에 숫자가 반드시 들어가야 한다
(?<...)형식을 사용한다.
(?<=Y)X
Y로 시작하는 X검색 -> YX
/(?<=\$)\d+/
$100 형식의 숫자를 찾는다
(?!...)형식을 사용하며 ...에 제외하고자 하는 패턴을 넣는다
file(?!\.exe)
뒤에 .exe가 붙지 않는 file을 찾는다 -> file.png or file.txt ...
^(?!.*\d).{8,}$
숫자를 포함하지 않는 8자리 이상 문자열
(?<!...)형식을 사용한다
(?<!\d)\w 앞에 숫자가 없는 문자를 검색
(?<!q)u 앞에 q가 없는 u를 검색
-> quack를 검색할 수 없다 = q(?!u)와 동일하다
/\.txt$/
/\(\d{3}\) \d{3}-\d{4}/
function isValidPhoneNumber(phoneNumber) {
const regex = /\(\d{3}\) \d{3}-\d{4}/;
return regex.test(phoneNumber);
}
console.log(isValidPhoneNumber("(123) 456-7890")); // true
console.log(isValidPhoneNumber("123-456-7890")); // false
console.log(isValidPhoneNumber("(123) 456-789")); // false
/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[\*\+\(\)\{\}\[\]\.]).{8,}$/
<c:out value="" /> 이스케이프 처리가 필요한 곳 찾을 때(?<!<c:out\s{1,5}escapeXml="true"\s+value=['"])(?<!<fmt:[^>]*)(?<!<c:set[^>]*)(?<!<codeUtils:[^>]*)(?<!items="[^"]*)(?<!test="[^"]*)(?<!<c:out\s{1,5}value=['"])(?<!<c:url\s{1,5}value=['"])\$\{(?![^}]*\b(codeManager|eq|empty|fn|ne)\b)([^}*\[\]<>+=\-]*\.[^}*\[\]<>+=\-]*)\}
(?<!<c:set[^>]*) -> <c:set ... > 내부를 검색에 포함하지 않음
\b(codeManager|eq|empty|fn|ne)\b는 파이프라인|으로 독립적인 단어들로 찾는다.
\b...\b를 사용해 각 단어들이 독립적으로 존재할 경우를 찾는다.
변경할 부분은 두번째 캡쳐 그룹을 사용 <c:out value="\${$2}" />
정규표현식 검색 시 *이나+가 들어간 검색은 성능이 좋지 않으므로 자세하게 검색하는게 좋다.
추가적으로 제외할 키워드를 추가한다면
(?<!style="[^"]*)(?<!id="[^"]*)(?<!for="[^"]*)(?<!class="[^"]*)
(?<!<script[^>]*)(?<!<tags:[^>]*)(?<!"javascript:[^"]*)(?<!'javascript:[^']*)
(?<!<c:set[^>]*)(?<!style="[^"]*)(?<!id="[^"]*)(?<!name="[^"]*)(?<!for="[^"]*)(?<!class="[^"]*)(?<!<script[^>]*)(?<!<tags:[^>]*)(?<!<fmt:[^>]*)(?<!"javascript:[^"]*)(?<!'javascript:[^']*)(?<!test="[^"]*)(?<!items="[^"]*)(?<!<codeUtils:[^>]*)(?<!<c:out value=")(?<!<c:out value=')(?<!<c:out escapeXml="true" value="[^"])\$\{(?![^}]*\b(codeManager|eq|empty|fn|ne)\b)([^}*\[\]<>+=\-]*\.[^}*\[\]<>+=\-]*)\}
(참고)
<td class="" value" 여기서 이스케이프 처리 시 오류 발생 " >
<c:if test=" 여기서 이스케이프 처리 시 오류 발생 ">
<c:set ~ 여기서 이스케이프 처리 시 오류 발생 >
let dateString = "2023-01-02";
let regex = /(\d{4})-(\d{2})-(\d{2})/;
let formattedDate = dateString.replace(regex, "$2/$3/$1");
console.log(formattedDate); // "01/02/2023"
let regExpNum = /[^a-zA-Z0-9]/g;
let regExpCiphers = /^(\w{0,3})(\w{0,3})(\w{0,6})$/g;
let regExpHyphen = /(\-{1,2})$/g;
elem.value = elem.value
.replace(regExpNum, '')
.replace(regExpCiphers, "$1-$2-$3")
.replace(regExpHyphen, "");
^(\w{0,3})(\w{0,3})(\w{0,6})$ 문자열을 3개의 캡쳐 그룹으로 나눈다. (문자열 최대 3자리, 3자리, 6자리)
^, $를 사용함으로써 세 그룹은 순서가 정해진다.
(\-{1,2})$ 는 문자열 끝에 1~2개의 -를 찾는다.
3개의 캡쳐 그룹은 '$1-$2-$3'의 모양으로 대체된다.
123abc456789 -> 123-abc-456789
let $schInput = document.querySelector('#recMedia');
let regExpNum = /[^0-9]/g;
let regExpCiphers = /^(\d{0,7})(\d{0,4})(\d{0,2})(\d{0,3})(\d{0,1})(\d{0,6})$/g;
let regExpHyphen = /(\-{1,5})$/g;
$schInput.value = $schInput.value.replace(regExpNum, '')
.replace(regExpCiphers, "$1-$2-$3-$4-$5-$6")
.replace(regExpHyphen, "");
function comma(str) {
str = String(str);
return str.replace(/(\d)(?=(?:\d{3})+(?!\d))/g, '$1,');
}
첫번째 (\d)는 숫자를 찾아 첫번째 캡쳐 그룹을 형성
(?=(?:\d{3})+(?!\d)):
긍정형 전방 탐색을 사용해 현재 위치에서 오른쪽으로 적어도 한 번 이상 반복되는 세 자리 숫자 그룹\d{3}이 있지만 그 바로 다음에 숫자가 오지 않는(?!\d) 위치를 찾는다
?:는 천 단위 구분자가 필요한 위치를 찾기 위해 캡쳐하지 않는 그룹을 나타낸다
$1,: 대체 문자열, 첫 번째 캡쳐 그룹(\d)에 해당하는 숫자 뒤에 콤마를 추가
function unComma(str) {
str = String(str);
return str.replace(/[^\d]+/g, '');
}
/[^\d]+/g는 하나 이상의 숫자가 아닌 문자를 찾아서 제거한다
숫자를 기준으로 문자열 나누기: `split("\\d+")`
단어 문자가 아닌 문자를 기준으로 문자열 나누기: `split("\\W+")`
알파벳이 아닌 문자로 문자열 나누기: `split("[^a-zA-Z]")`
단어 경계를 기준으로 문자열 나누기: `split("\\b")`
// 특수문자, 괄호, 점, 공백 모두 제거
let reg = /[`~!@#$%^&*()_|+\-=?;:'",.<>\{\}\[\]\\\/ ]/gim;
// 특수문자, 괄호, 점 모두 제거 - 공백은 제거 안함
let reg = /[`~!@#$%^&*()_|+\-=?;:'",.<>\{\}\[\]\\\/]/gim;
//특수문자, 괄호, 공백 모두 제거 - 점은 제거 안함
let reg = /[`~!@#$%^&*()_|+\-=?;:'"<>\{\}\[\]\\\/ ]/gim;
//정규식에 해당하는 문자를 replace 로 제거
let resultData = originalData.replace(reg, "");