정규표현식(Regular Expression)
- 정규표현식(Regular Expression) 줄여서 Regex 라고 표현
- 특정한 규칙을 가진 무자열의 집합을 표혀낳는 사용하는 형식 언어
- 문자열에서 특정 패턴을찾거나 존재하는지, 또는 검증할 때 사용
- 정규 표현식의 각 문자(즉, 패턴을 기술하는 문자열 안의 각 문자)는 메타문자(특별한 의미로)로 이해되거나 정규 문자('문자 그대로', 즉 '리터럴'의 의미로)로 이해된다
- 정규식 a. a는 단지 'a'와 일치하는 리터럴 문자이며 .는 새 줄을 제외한 모든 문자와 일치시키는 메타 문자이다
Java에서의 정규표현식
- java.util.regex 패키지에 있는 클래스들을 사용한다.
- Pattern클래스 - 패턴 정의(검색에 사용됨)
- Matcher클래스 - 패턴 검색에 사용
- PatternSyntaxException클래스 - 정규식 패턴의 구문 오류를 나타냅니다.
정규 표현식의 Pattern클래스의 matchers()메서드를 사용하여 해당문자열이 패턴과 일치하는지 확인합니다 matches(String regex, CharSequence input)을 사용합니다
- public static boolean matches(String regex, CharSequence input)
- 패턴에 일치하면 true 틀리면 false를 반환
@Test
void regexTest() {
String pattern = "^[a-zA-Z]*$"; //영어만
String str = "abcde";
boolean matches = Pattern.matches(pattern, str);
System.out.println(matches); // 패턴에 맞으므로 true 반환
}
Pattern 클래스 주요 메서드
- compile(String regex) : 정규표현식의 패턴을 작성
- matches(String regex, CharSequence input)
- 정규표현식의 패턴과 문자열이 일치하는지 체크
- 일치할 경우 true, 일치하지 않는 경우 false를 리턴
Matcher 클래스 주요 메서드
- matches()
- 정규표현식의 패턴과 문자열이 일치하는지 체크
- 일치할 경우 true, 일치하지 않는 경우 false를 리턴
- find()
- 정규표현식의 패턴과 문자열이 일치하는지 체크합니다 그리고 그 위치로 이동
- 일치할 경우 true, 일치하지 않는 경우 false를 리턴
- find(int start)
- start위치부터 find() 작업을 수행
- group()
- 매칭된 부분 중 첫 번째 그룹을 리턴합니다
- group(int group)
- 매칭된 부분중 group번째 그룹을 리턴합니다
- 범위를 벗어나면 IndexOutOfBondsException 발생
- groupCount()
- 매칭된 group의 전체 갯수를 리턴합니다
- 다음과 같이 사용할 수도 있다.
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args) {
Pattern pattern = Pattern.compile("pattern", Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher("패턴");
boolean matchFound = matcher.find();
if(matchFound) {
System.out.println("Match found");
} else {
System.out.println("Match not found");
}
}
}
- Pattern.compile()먼저 메서드 를 사용하여 패턴을 만듭니다.
- 첫 번째 매개변수는 검색 중인 패턴을 나타내고 두 번째 매개변수에는 검색이 대소문자를 구분하지 않아야 함을 나타내는 플래그가 있습니다.
- 두 번째 매개변수는 선택 사항입니다.
- matcher()메서드는 문자열에서 패턴을 검색하는 데 사용됩니다. 수행된 검색에 대한 정보가 포함된 Matcher 개체를 반환합니다.
- find()메서드는 문자열에서 패턴을 찾으면 true를 반환하고 찾지 못하면 false를 반환합니다.
메서드 의 Flag compile()는 검색이 수행되는 방식을 변경한다.
- Pattern.CASE_INSENSITIVE- 검색시 대소문자는 무시됩니다.
- Pattern.LITERAL- 패턴의 특수문자는 특별한 의미가 없으며 검색시 일반문자로 처리됩니다.
- Pattern.UNICODE_CASE- 플래그와 함께 사용하여 CASE_INSENSITIVE영문자 이외의 문자도 무시
java에서의 정규표현식의 활용
- 문자열에서 알파벳 대문자, 숫자, 더하기(+), 밑줄(_), 마침표(.)를 제외한 모든 문자를 제거하라
- 문자열에서 마침표(.)가 3번 이상 연속된 부분을 하나의 마침표(.)로 치환하라
private String removeChar(String input) {
return input.replaceAll("[^A-Z0-9+_.]", ""); // 1번. 제거
}
private String changeDot(String input) {
return input.replaceAll("[.]{3,}", "."); // 2번 .로 replace
}
String Class의 replaceAll() 메서드
public String replaceAll(String regex, String replacement) {
return Pattern.compile(regex).matcher(this).replaceAll(replacement);
}
- Pattern.compile()을 사용하고 있다.
/// Pattern.compile() 메서드
/**
* Compiles the given regular expression into a pattern.
*
* @param regex
* The expression to be compiled
* @return the given regular expression compiled into a pattern
* @throws PatternSyntaxException
* If the expression's syntax is invalid
*/
public static Pattern compile(String regex) {
return new Pattern(regex, 0);
}
- 항상 패턴으로 새로운 패턴을 만든다. (new)
- 사실상 패턴을 바뀔일이 없으므로 pattern을 정적 상수로 선언하여 재활용성을 높이자
private static final Pattern REMOVE_CHAR_PATTERN = Pattern.compile("[^A-Z0-9+_.]");
private static final Pattern CHANGE_DOT_PATTERN = pattern.compile("[.]{3,}");
private String removeChar(String input) {
return REMOVE_CHAR_PATTERN.matcher(input).replaceAll("");
}
private String changeDot(String input) {
return CHANGE_DOT_PATTERN.matcher(input).repliaceAll(".");
}
Pattern 클래스는 정적 팩토리 메서드를 사용하고 있으며 Thread-safe 하다
Pattern 객체는 불변 객체이다.
Matcher 클래스 사용시 주의할점
Matcher 객체는 reset() 하고 다시 input 값을 넣어서 재사용해줄 수 있지만 Thread-safe 하지못하다.
- Matcher Class의 reset() 메서드
public Matcher reset() {
....
return this;
}
그러므로 Thread-safe 하게 사용하려면 Pattern 객체의 matcher()를 통해 Matcher를 새로 생성한 뒤 사용하자
정규표현식 문법
Regular ExpressionsDescriptionExample
. | 임의의 문자 1개를 의미 | |
^ | 시작을 의미한다. [ ] 괄호 안에 있다면 일치하지 않는 부정의 의미로로 쓰인다 | ^a : a로 시작하는 단어 a : a가 아닌 철자인 문자 1개 예를 들면 abcd는 ad, bd, cd는 포함하지 않고 ed, fd 등을 포함한다. a-z는 알파벳 소문자로 시작하지 않는 모든 문자를 의미 |
$ | $앞의 문자열로 문자가 끝나는지를 의미한다. 문자열의 끝 | a$ : a로 끝나는 단어 |
[] | [] 괄호 안의 문자가 있는지를 확인한다 | ab : a,b중 한 문자와 c,d중 한 문자 -> ac ad bc bd [xy] 문자 선택을 표현하며 x 와 y 중에 하나를 의미한다. xy not 을 표현하며 x 및 y 를 제외한 문자를 의미한다. [x-z] range를 표현하며 x ~ z 사이의 문자를 의미한다. |
- | 사이의 문자 혹은 숫자를 의미한다 | 출처: https://hamait.tistory.com/342 HAMA 블로그:티스토리 : 알파벳 소문자 a부터 z까지. [a-z0-9] : 알파벳 소문자 전체,0~9 중 한 문자 예를 들면 [abc]d는 ad, bd, cd를 뜻한다. 또한, "-" 기호와 함께 쓰면 범위를 지정할 수 있다. "[a-z]"는 a부터 z까지 중 하나, "[1-9]"는 1부터 9까지 중의 하나를 의미한다. |
| | or 조건 (또는). 왼쪽 호는 오른쪽과 일치 | [a|b] : a 혹은 b |
() | 그룹 | 01 (0|1) : 01뒤에 0 또는 1이 들어간다 -> 010(o), 011(o), 012(x) |
{} | 개수 | a{3}b : a가 3번 온 후 b가 온다 -> aab(x), aaab(o), aaaab(o) |
\b | 공백, 탭, ",", "/" 등을 의미한다 | apple\b : apple뒤에 공백 탭등이 있다 -> apple juice (o), apple.com (x) |
\B | \b의 부정 공백 탭등이 아닌 문자인 경우 매치한다 | apple\b -> apple.com (o) |
\d | 0~9 사이의 숫자 [0-9]와 동일 | |
\D | \d의 부정 숫자가 아닌 어떤 문자, 0-9와 동일 | |
\s | 공백, 탭 | |
\S | 공백, 탭이 아닌 문자 | |
\w | 알파벳 대소문자+숫자+"_" [a-zA-Z_0-9]와 동일 | |
\W | \w의 부정 a-zA-Z_0-9 | |
\A | 문자열의 시작점을 일치시킨다. | |
\z | 문자열의 끝 | |
\s | 공백 문자 | |
\S | 공백문자가 아닌 나머지와 일치 |
위치 문자설명
^a | 단어의 맨 앞에 위치한 해당 패턴만을 검색함. (ex : 'a'로 시작하는 단어의 'a'만을 검색함.) |
a$ | 단어의 맨 뒤에 위치한 해당 패턴만을 검색함. (ex : 'a'로 끝나는 단어의 'a'만을 검색함.) |
수량 표현식
Regular ExpressionsDescriptionExample
? | 앞의 표현식이 0개 이상이다 | a1? : 1이 있을수도 없을수도 있다 -> a (o), a1(o), a2(o) |
* | 앞의 표현식이 0개 이상이다. 문자가 없는 경우나 하나 이상 연속하는 문자 찾기. | a1* : 1이 있을수도 없을수도 있다 -> a (o), a1(o), a2(o) |
+ | 1개 이상 찾기. | a1* : 1이 1개 이상있다 -> a (x), a1(o), a11(o) |
{n} | n개 있다 (n번 반복) | a{3} : a가 3개 있다 -> aa(x), aaa(o), aaaa(o) |
{n, m} | n개 이상 m개 이하 | a{3,5} : a가 3개 or 4개 or5개 있다 -> aa(x), aaa(o), aaaa(o), aaaaaaa(o) |
{n,} | n개 이상(m제거), (n번 이상 반복) | a{3,} : a가 3개 이상 있다 -> aa(x), aaa(o) |
괄호설명
a(b)c | 전체 패턴을 검색한 후에 괄호 안에 명시된 문자열을 저장함. (ex : "abc"를 검색한 후에 b를 저장함.) |
[abc] | 꺾쇠 괄호([]) 안에 명시된 문자를 검색함. (ex : "abc"를 검색함.) |
[0-3] | 꺾쇠 괄호([]) 안에 명시된 숫자를 검색함. (ex : 0부터 3까지의 숫자를 검색함.) |
[\b] | 백스페이스 문자를 검색함. |
{n} | 앞의 문자가 정확히 n번 나타나는 경우를 검색함. n은 반드시 양의 정수이어야만 함. |
{m,n} | 앞의 문자가 최소 m번 이상 최대 n번 이하로 나타나는 경우를 검색함. m과 n은 반드시 양의 정수이어야만 함. |
- Escape: 정규표현식 패턴이 아닌 문자로 사용하고 싶을때는 앞에 \(역슬래시)를 앞에 붙이기
Flag
정규표현식을 사용할 때 Flag 라는 것이 존재하는데 Flag를 사용하지 않으면 문자열에 대해서 검색을 한번만 처리하고 종료하게 된다.
Flag는 다음과 같은 것들이 존재한다.
Flag의미
g | Global 을 표현하며, 대상 문자열 내에 모든 패턴들을 검색하는것을 의미. |
i | Ignore case 을 표현하며 대상 문자열에 대해서 대/소문자를 구별하지 않는것 |
m | Multi line을 표현하며 대상 문자열이 다중 라인의 문자열인 경우에도 검색하는 것을 의미한다. 행이 바뀌어도 찾는다. |
전방 탐색
이외의 방식
자주 사용하는 정규표현식 예제
- ^[0-9]*$ : 숫자
- ^[a-zA-Z]*$ : 영문자
- ^[가-힣]*$ : 한글
- ^([가-힣]+[0-9]*)$ : 한글로 된 문자가 꼭 포함 되어야 하며, 숫자가 있어도 됨
- ^([가-힣]+[0-9]{0,3})$ : 한글로 된 문자가 꼭 포함 되어야 하며 숫자는 있어도 된다. (숫자의 개수는 3개 제한)
- \w+@\w+\.\w+(\.\w+)? : 이메일 주소
- ^\d{2,3}-\d{3,4}-\d{4}$ : 전화번호
- ^01(?:0|1|[6-9])-(?:\d{3}|\d{4})-\d{4}$ : 핸드폰 번호
- \d{6} - [1-4]\d{6} : 주민등록 번호
- ^\d{3}-\d{2}$ : 우편번호
- https://codechacha.com/ko/java-regex/
- https://noritersand.github.io/misc/misc-regexp-%EC%A0%95%EA%B7%9C-%ED%91%9C%ED%98%84%EC%8B%9D-%EB%AA%A8%EC%9D%8C