해당 포스팅은 https://school.programmers.co.kr/learn/courses/11/11-%EC%A0%95%EA%B7%9C%ED%91%9C%ED%98%84%EC%8B%9D 에서 학습한 내용을 토대로 작성합니다.
인프런에서 자바 알고리즘 문제중 문자열 관련 강의를 수강하다가 replaceAll 메소드를 사용하는 모습을 보았고 이때 정규식에 무지한 나는 정규식을 학습 할 필요가 있다고 생각하여 이 포스팅을 작성하게 되었다.
정규표현식(regex)이란?
텍스트에서 원하는 조건과 일치하는 문자열을 찾아내거나 원하는 조건과 텍스트가 일치하는지 참/거짓 여부를 판단하는 등의 상황에 사용된다.
예를 들어, 여러 사람이 있는 경우 이름이 a로 시작하는 사람을 찾아내거나, 사용자가 입력한 문자열이 이메일 형식에 맞는지 참/거짓 여부를 판단하는 등에 사용할 수 있다.
String str = "This is sample sentence";
str = str.replaceAll("s{1,}", "ss");
System.out.println(str); // Thiss iss ssample ssentence
위와 같이 replaceAll 메소드의 첫번째 인자로 들어간 "s{1,}" 이 regex이다. 의미는 앞에 문자 s가 1번 이상 반복되는 경우를 뜻하며 s가 1번 이상 반복되는 경우는 ss로 치환한다.
정규표현식에 사용되는 표현식
- .a : 임의문자 + a
- a* : a의 0번 이상 반복(없어도 되고 있어도 되고)
- a+ : a의 1번 이상 반복(무조건 하나라도 존재)
- + : 하나 혹은 그 이상 연결된
- ^a : 문자열이 a로 시작
- a$ : 문자열이 a로 끝남
- a? : a가 존재할 수도, 존재하지 않을 수도 있다
- Ex) ab?c : ac, abc 둘 다 가능
- a|b : a 또는 b
- a{n} : a의 n번 반복
- a{m, n} : a의 m번 이상, n번 이하 반복
- a{n, } : a의 n번 이상 반복
- [xy] : x또는 y 한 문자
- [x-z] : x~z 범위 내의 한 문자
- [^xy] : x 또는 y를 제외한 한 문자
- Ex) [^yz] : a, b, c , d, ... , w, x 중 한 문자를 의미. (y와 z를 제외한 문자)
- \d : 숫자와 매치
- [0-9]와 동일한 표현식
- \D : 숫자가 아닌 것과 매치
- [^0-9]와 동일한 표현식
- \s : 공백 문자와 매치
- [ \t\n\r\f\v]와 동일한 표현식. 맨 앞의 빈칸은 공백문자(space)를 의미
- \S : 공백 문자가 아닌 것과 매치
- [^ \t\n\r\f\v]와 동일한 표현식
- \S+ 와 같이 사용하면 공백을 기준으로 단어를 나눌 수 있다.
- \w : 문자 + 숫자와 매치
- [a-zA-Z0-9_]와 동일한 표현식
- 특수문자 '_'를 포함한다.
- \W : 문자 + 숫자가 아닌 것과 매치
- [^a-zA-Z0-9_]와 동일한 표현식
- 특수문자 '_'를 포함한다.
예제
1. 한글로 된 문자가 꼭 포함되어야 하며, 숫자가 있어도 된다
^[(가-힣)+[0-9]*)$
// 1. 한글로 된 문자가 꼭 포함되어야 하며 숫자가 있어도 된다
Pattern pattern1 = Pattern.compile("^([가-힣]+[0-9]*)$");
System.out.println(pattern1.matcher("가가").matches()); // true
System.out.println(pattern1.matcher("가가123").matches()); // true
System.out.println(pattern1.matcher("가가aaa").matches()); // false
System.out.println(pattern1.matcher("aa").matches()); // false
System.out.println(pattern1.matcher("123").matches()); // false
2. 한글로 된 문자가 꼭 포함되어야 하며, 숫자는 있어도 된다. (단, 숫자의 개수는 3이 최대)
^[(가-힣)+[0-9]{0,3})$
// 2. 한글로 된 문자가 꼭 포함되어야 하며 숫자는 있어도 된다. (단, 숫자의 개수는 3이 최대)
Pattern pattern2 = Pattern.compile("^([가-힣]+[0-9]{0,3})$");
System.out.println(pattern2.matcher("히하흐").matches()); // true
System.out.println(pattern2.matcher("히하흐123").matches()); // true
System.out.println(pattern2.matcher("히하흐7777777").matches()); // false
System.out.println(pattern2.matcher("히하33흐").matches()); // false
3. 주소록에서 전화번호만 찾는 정규표현식
0\d{1,2}[ -]?\d{3,4}[ -]?\d{3.4}
4. \d는 숫자 한글자만 찾는다. 그런데, 전화번호를 구성하는 숫자와 같이(010, 043, ...) 연결된 숫자를 찾고싶을 때
\d+
여기서 +는 "하나 혹은 그 이상 연결된" 이라는 뜻이다.
5. 정규표현식으로 010, 123, 456 중 자연수를 찾는 정규식
[1-9]\d*
- 자연수는 0으로 시작하지 않으니 첫자리는 반드시 1~9중 하나
- 그 다음 자리부터는 0~9 사이의 숫자가 나올 수도 있고 나오지 않을 수도 있다
즉, 자연수는 처음에 1~9중 하나의 숫자가 나온 다음 그 뒤에는 숫자가 0개 이상 나오면 자연수이다.
6. 전화번호는 "-"을 포함할수도 포함하지 않을수도 있다. 유효한 전화번호를 찾는 정규식
\d+-?\d+-?\d+
- -?는 "-가 있거나 없다"를 의미한다.
- \d+ 는 연속하는 숫자를 의미하므로 이와 조합하면 전화번호를 찾는 정규표현식을 만들 수 있다.
- 단, 이는 공백이 포함된 전화번호는 찾을 수 없다.
7. 공백이 포함된 모든 전화번호를 찾는 정규식
\d+[ -]?\d+[ -]?\d+
- - 또는 공백이 있거나 없다는 조건은 [ -]? 로 표현
- -?는 "-가 있거나 없다" 라는 조건이므로 한계가 있음
- "- 또는 공백이 있거나 없다"라는 조건을 사용해야 한다
- 단, 이 방법은 000300586-6-3125125 와 같이 연결된 숫자가 너무 많은 문자열도 전화번호라고 인식한다.
8. 알파벳 중에 소문자 모음(a,e,i,o,u)만 고르는 정규식
[aeiou]
9. 소문자 알파벳만 고르는 정규식
[a-z]
- a부터 z까지 글자를 모두 선택하라
10. 연속된 영어 소문자를 찾는 정규식
[a-z]+
- 소문자를 뜻하는 [a-z]
- 반복을 뜻하는 +
11. 한글 단어를 찾는 정규식
[가-힣]+
- 단, 이 방법으로는 "ㄱㄴㄷ"나 "ㅏㅑㅓㅕ"같은 낱글자는 찾을 수 없다.
자바 정규표현식
Java에서는 \ 대신 \\를 사용해야 한다. 자바에선 escape때문에 역슬래시를 사용해 역슬래시 \를 두 번 적어야 한다.
public static void main(String[] args) {
String str = "This is sample sentence";
str = str.replaceAll("\\w+", "ss");
System.out.println(str); // ss ss ss ss
}
Reference
- https://gh402.tistory.com/54
'Algorithm > Programmers' 카테고리의 다른 글
[프로그래머스|최대공약수와 최소공배수] 유클리드 호제법 (0) | 2022.08.31 |
---|---|
[프로그래머스|숫자 문자열과 영단어] replaceAll 함수 (0) | 2022.08.29 |
[프로그래머스] 모의고사 (0) | 2022.08.09 |
[프로그래머스]Level2 주식가격<java> (0) | 2022.02.18 |
[프로그래머스]Level2 기능개발 <java> (0) | 2022.02.18 |