아래 내용은 Java JDK에 있는 내용을 재 정리 한것이다. (시간이 되면 번역을 할까 생각중인데, 궂이 그럴필요가...)
가장 먼저 특수 문자에 대해서 알아보자. 각각의 8진수, 16진수, tab, 이스케이프 문자등을 나타내기 위해서는 다음과 같이 사용하면 된다.
x The character x \\ The backslash character \0n The character with octal value 0n (0 <= n <= 7) \0nn The character with octal value 0nn (0 <= n <= 7) \0mnn The character with octal value 0mnn (0 <= m <= 3, 0 <= n <= 7) \xhh The character with hexadecimal value 0xhh \uhhhh The character with hexadecimal value 0xhhhh \t The tab character ('\u0009') \n The newline (line feed) character ('\u000A') \r The carriage-return character ('\u000D') \f The form-feed character ('\u000C') \a The alert (bell) character ('\u0007') \e The escape character ('\u001B') \cx The control character corresponding to x
그 다음에는 문자를 표현하는 방식을 보자. 특정 범위의 문자나 범위 이외의 문자는 다음과 같이 표시한다.
[abc] a, b, or c (simple class) [^abc] Any character except a, b, or c (negation) [a-zA-Z] a through z or A through Z, inclusive (range) [a-d[m-p]] a through d, or m through p: [a-dm-p] (union) [a-z&&[def]] d, e, or f (intersection) [a-z&&[^bc]] a through z, except for b and c: [ad-z] (subtraction) [a-z&&[^m-p]] a through z, and not m through p: [a-lq-z](subtraction)
위의 방식을 사용하여 정의할 수도 있겠지만, 다음과 같이 미리 정의된 문자열을 사용하면 보다 편하게 사용 가능하다.
. Any character (may or may not match line terminators) \d A digit: [0-9] \D A non-digit: [^0-9] \s A whitespace character: [ \t\n\x0B\f\r] \S A non-whitespace character: [^\s] \w A word character: [a-zA-Z_0-9] \W A non-word character: [^\w]
\p{Lower} A lower-case alphabetic character: [a-z] \p{Upper} An upper-case alphabetic character:[A-Z] \p{ASCII} All ASCII:[\x00-\x7F] \p{Alpha} An alphabetic character:[\p{Lower}\p{Upper}] \p{Digit} A decimal digit: [0-9] \p{Alnum} An alphanumeric character:[\p{Alpha}\p{Digit}] \p{Punct} Punctuation: One of !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~ \p{Graph} A visible character: [\p{Alnum}\p{Punct}] \p{Print} A printable character: [\p{Graph}\x20] \p{Blank} A space or a tab: [ \t] \p{Cntrl} A control character: [\x00-\x1F\x7F] \p{XDigit} A hexadecimal digit: [0-9a-fA-F] \p{Space} A whitespace character: [ \t\n\x0B\f\r]
자바의 Character 클래스와 같은 방식으로 사용하려면 다음과 같이 사용 가능하다.
\p{javaLowerCase} Equivalent to java.lang.Character.isLowerCase() \p{javaUpperCase} Equivalent to java.lang.Character.isUpperCase() \p{javaWhitespace} Equivalent to java.lang.Character.isWhitespace() \p{javaMirrored} Equivalent to java.lang.Character.isMirrored()
유니코드를 처리하기 위해서는 다음과 같이 사용하면 된다. (한글에 대해서는 아직 테스트 해보지 않았다. ^^)
\p{InGreek} A character in the Greek block (simple block) \p{Lu} An uppercase letter (simple category) \p{Sc} A currency symbol \P{InGreek} Any character except one in the Greek block (negation) [\p{L}&&[^\p{Lu}]] Any letter except an uppercase letter (subtraction)
각 경계값을 나타내는 것은 다음과 같이 할 수 있다.
^ The beginning of a line $ The end of a line \b A word boundary \B A non-word boundary \A The beginning of the input \G The end of the previous match \Z The end of the input but for the final terminator, if any \z The end of the input
이제부터 정신을 바짝 차려야 하는데, 위의 각 방법을 조합해서 각 문자의 횟수를 다음과 같이 지정할 수 있다. (이를 Greedy quantifiers라고 부른다.)
X? X, once or not at all X* X, zero or more times X+ X, one or more times X{n} X, exactly n times X{n,} X, at least n times X{n,m} X, at least n but not more than m times
그리고, ? 와 +를 사용하여 각각 제외 및 포함의 의미를 나타낸다. 각 예는 다음과 같다.
Reluctant quantifiers X?? X, once or not at all X*? X, zero or more times X+? X, one or more times X{n}? X, exactly n times X{n,}? X, at least n times X{n,m}? X, at least n but not more than m times
Possessive quantifiers X?+ X, once or not at all X*+ X, zero or more times X++ X, one or more times X{n}+ X, exactly n times X{n,}+ X, at least n times X{n,m}+ X, at least n but not more than m times
논리 부분은 다음과 같이 표시한다.
XY X followed by Y X|Y Either X or Y (X) X, as a capturing group
특수 Construct는 다음과 같다.
(?:X) X, as a non-capturing group (?idmsux-idmsux) Nothing, but turns match flags i d m s u x on - off (?idmsux-idmsux:X) X, as a non-capturing group with the given flags i d m s u x on - off (?=X) X, via zero-width positive lookahead (?!X) X, via zero-width negative lookahead (?<=X) X, via zero-width positive lookbehind (?<!X) X, via zero-width negative lookbehind (?>X) X, as an independent, non-capturing group
기타 관련 Construct들은 다음과 같다.
Back references \n Whatever the nth capturing group matched
Quotation \ Nothing, but quotes the following character \Q Nothing, but quotes all characters until \E \E Nothing, but ends quoting started by \Q
이 내용들에 대해서는 한번 쭉~~~ 읽어보면 이해가 되겠지만, 예제를 봐야지만 보다 더 쉽게 이해할 수 있으리라 생각된다.
다음 글에는 예제를 통해서 각 Regular Expression을 어떻게 사용하는지 정리하도록 하겠다.
public static void main(String[] args){ RegexTester rt=new RegexTester(); while(true) { rt.checkRegularExpression(); } } public void checkRegularExpression() { Scanner sc=new Scanner(System.in); System.out.print("Enter Regular expression pattern : "); String regex=sc.nextLine(); while(check(regex)); } public boolean check(String regex) { Scanner sc=new Scanner(System.in); System.out.print("Enter data: "); String data=sc.nextLine(); Pattern samplePattern = Pattern.compile(regex); Matcher matcher = samplePattern.matcher(data); boolean found = false; while (matcher.find()) { System.out.format("Text \"%s\" is found : from index %d - to index %d.\n", matcher.group(), matcher.start(), matcher.end()); found = true; } if(!found){ System.out.format("No match found.\n"); } System.out.print("Check another data ? [Y or y] or Quit [Q or q] : "); String another=sc.nextLine(); if(another.equals("Q") || another.equals("q")) { System.exit(0); return false; } else if(another.equals("Y") || another.equals("y")) { return true; } else { return false; } }
}
이 프로그램은 Regular Expression을 입력하고, 문자열을 입력하면 입력된 문자열중 Regular Expression과 맞는 (match되는) 문자열이 어떤것이 있는지를 화면에 뿌려준다.
실행 결과 예는 다음과 같다.
Enter Regular expression pattern : [abc] Enter data: abcdefg Text "a" is found : from index 0 - to index 1. Text "b" is found : from index 1 - to index 2. Text "c" is found : from index 2 - to index 3. Check another data ? [Y or y] or Quit [Q or q] : y Enter data: No match found. Check another data ? [Y or y] or Quit [Q or q] : y Enter data: cbfhgft Text "c" is found : from index 0 - to index 1. Text "b" is found : from index 1 - to index 2. Check another data ? [Y or y] or Quit [Q or q] : q