특정한 규칙을 가진 문자열의 집합을 표현하는 데 사용하는 형식 언어이다.
문자열에 어떤 패턴의 문자들을 찾고자 할 때 유용하게 쓰일 수 있다.
^regex : 문자열의 시작이 regex에 해당하는 경우
regex$ : 문자열의 끝이 regex에 해당하는 경우
String result1, result2;
String str = ".123!";
result1 = str.replaceAll("^.", "*");
System.out.println(result1);
result2 = str.replaceAll("!$", "*");
System.out.println(result2);
// 출력
*123!
.123*
[abc] : a, b, c 중 문자 1개
[abc][xyz] : a, b, c 중 문자 1개와 x, y, z 중 문자 1개 조합
[^abc] : a, b, c 제외한 문자 1개
String str = "This is a book.";
System.out.println(str.replaceAll("[abc]", "*"));
System.out.println(str.replaceAll("[ijk][opqrs]", "*"));
System.out.println(str.replaceAll("[^This]", "*"));
This is * *ook. // a, b -> *
Th* * my book. // (i,j,k)와 (o,p,q,r,s)의 조합인 is -> *
This*is********* // (T,h,i,s)에 포함되지 않은 문자 -> * (공백도 포함되지 않은 문자다)
[0-9] : 0~9 사이 숫자
[a-z] : 소문자 a~z 사이 문자
[A-Z] : 대문자 A~Z 사이 문자
[a-zA-Z] : 알파벳 문자
String str = "Contact : 010-1234-5678";
System.out.println(str.replaceAll("[0-9]", "*"));
System.out.println(str.replaceAll("[a-z]", "*"));
System.out.println(str.replaceAll("[A-Z]", "*"));
System.out.println(str.replaceAll("[a-zA-Z]", "*"));
Contact : ***-****-****
C****** : 010-1234-5678
*ontact : 010-1234-5678
******* : 010-1234-5678
X{n} : X가 정확히 n개 존재
X{n, } : X가 최소 n개 존재
X{n, m} : X가 n개 이상 m개 이하 존재
String str = "aaa.bbbb.cc.aa.b.ccc.a";
System.out.println(str.replaceAll("a{2}|b{3}|c{1}", "*"));
System.out.println(str.replaceAll("a{2,}|b{3,}|c{1,}", "*"));
System.out.println(str.replaceAll("a{2,3}|b{3,4}|c{1,3}", "*"));
*a.*b.**.*.b.***.a
*.*.*.*.b.*.a
*.*.*.*.b.*.a
String.matches(regex)
: Stirng이 regex와 일치하면 true 리턴String.split(regex)
: regex와 일치하는 것을 기준으로 String을 분리하여 배열로 리턴String.replaceAll(regex, replacement)
: regex와 일치하는 모든 것을 replacement로 변환[문제] 신규 유저가 입력한 아이디를 나타내는 new_id가 매개변수로 주어질 때, "네오"가 설계한 7단계의 처리 과정을 거친 후의 추천 아이디를 return
1단계 new_id의 모든 대문자를 대응되는 소문자로 치환합니다. 2단계 new_id에서 알파벳 소문자, 숫자, 빼기(-), 밑줄(_), 마침표(.)를 제외한 모든 문자를 제거합니다. 3단계 new_id에서 마침표(.)가 2번 이상 연속된 부분을 하나의 마침표(.)로 치환합니다. 4단계 new_id에서 마침표(.)가 처음이나 끝에 위치한다면 제거합니다. 5단계 new_id가 빈 문자열이라면, new_id에 "a"를 대입합니다. 6단계 new_id의 길이가 16자 이상이면, new_id의 첫 15개의 문자를 제외한 나머지 문자들을 모두 제거합니다. 만약 제거 후 마침표(.)가 new_id의 끝에 위치한다면 끝에 위치한 마침표(.) 문자를 제거합니다. 7단계 new_id의 길이가 2자 이하라면, new_id의 마지막 문자를 new_id의 길이가 3이 될 때까지 반복해서 끝에 붙입니다.
정규식을 활용하면 쉽게 풀 수 있는 재밌는 문제다.
정규식을 사용할 수 있는 단계는 2, 3, 4, 6단계이다.
단계별로 하나씩 풀어보자.
[1단계] 모든 대문자를 대응되는 소문자로 치환
String str = new_id.toLowerCase();
toLowerCase()
메서드를 사용해 모든 문자열을 소문자로 만든다.[2단계] 알파벳 소문자, 숫자, 빼기(-), 밑줄(_), 마침표(.)를 제외한 모든 문자를 제거
str = str.replaceAll("[^a-z0-9-_.]", "");
[^a-z0-9-_.]
: a~z 소문자, 0~9 숫자, 기호(-, _, .)를 제외(^)한 문자들을 지운다.[3단계] 마침표(.)가 2번 이상 연속된 부분을 하나의 마침표(.)로 치환
str = str.replaceAll("[.]{2,}", ".");
str = str.replaceAll("\\.{2,}", ".");
[.]{2,}
: 마침표(.)가 2번 이상 반복되면 “.” 마침표 하나로 바꾼다.\\.{2,}
: 이렇게 써도 된다. 특수문자를 정규식에서 바로 사용할 때 백슬래시(\
)를 두번 사용한다.[4단계] 마침표(.)가 처음이나 끝에 위치한다면 제거
str = str.replaceAll("^[.]|[.]&", "");
str = str.replaceAll("^\\.|\\.&", "");
^[.]|[.]&
: 문자열의 처음이 “.” 이거나, 문자열의 마지막이 “.”인 경우 제거^\\.|\\.&
: 이렇게 써도 된다. 백슬래시(\
) 두 번 사용[5단계] 빈 문자열이라면, "a"를 대입
str = str.isEmpty() ? "a" : str;
isEmpty()
: 문자열이 비어있는지 확인[6단계] 길이가 16자 이상이면, 첫 15개의 문자를 제외한 나머지 문자들을 모두 제거
만약 제거 후 마침표(.)가 문자열의 끝에 위치한다면 끝에 위치한 마침표(.) 문자를 제거
if (str.length() >= 16) {
str = str.substring(0, 15);
}
str = str.replaceAll("[.]$", "");
substring(int from, int to)
: 문자열의 인덱스 from부터 인덱스 (to - 1)까지 문자열 자르기[.]$
: 문자열 마지막이 “.”로 끝난다면 제거[7단계] 길이가 2자 이하라면, 마지막 문자를 길이가 3이 될 때까지 반복해서 끝에 붙이기
if (str.length() <= 2)
while (str.length() < 3)
str += str.charAt(str.length()-1);
str.charAt(str.length()-1)
: 문자열의 마지막 인덱스의 글자