title
[!quote] Definition
A compiled representation of a regular expression.
A regular expression, specified as a string, must first be compiled into an instance of this class. The resulting pattern can then be used to create a
Matcherobject that can match arbitrary java.lang.CharSequence character sequences against the regular expression. ==All of the state involved in performing a match resides in the matcher==, so many matchers can share the same pattern.A typical invocation sequence is thus
Pattern p = Pattern.compile("a*b"); Matcher m = p.matcher("aaaaab"); boolean b = m.matches();
1. Pattern::compile
Patternμ μμ±μλ privateμΌλ‘ μΈλΆ μ κ·Όμ΄ μ νλμ΄ μλ λμ , μ μ ν©ν 리 λ©μλ compileμ μ 곡νλ€. μ»΄νμΌμ΄λΌλ λμμ νννκΈ° μν΄ μ¬μ©λμμ λΏ, μ€μ§μ μΌλ‘ λ΄λΆμ μμ±μλ₯Ό
νΈμΆνλ ==λ리μ==μ λΆκ³Όνλ€.
/*
* This private constructor is used to create all Patterns. The pattern
* string and match flags are all that is needed to completely describe
* a Pattern. An empty pattern string results in an object tree with
* only a Start node and a LastNode node.
*/
private Pattern(String p, int f) { ... }
// ...
public static Pattern compile(String regex) {
return new Pattern(regex, 0);
}
public static Pattern compile(String regex, int flags) {
return new Pattern(regex, flags);
}
[!info]+ Info: IDE ννΈ
IntelliJμμ μ‘°νν API λ¬Έμλ₯Ό μ΄ν΄λ³΄λ©΄
org.intellij.lang.annotations.MagicConstantλΌλ IDE λ΄λΆ μ΄λ Έν μ΄μ μ΄ μ‘΄μ¬νλ€. μ΄ λλΆμcompileλ©μλμ νλκ·Έλ₯Ό μ€μ ν λ, λ€μκ³Ό κ°μ΄ ν΄λΉ ν΄λμ€μ μ μλ μμλ€μ λ¨Όμ μΆμ²λ°μ μ μκ² λλ€. (DOTALLλΆν°UNIX_LINESλͺ¨λ μμμ ν΄λΉ)
μμ μ μμ λͺ μλμ΄ μμ§λ μμ§λ§, regex νλΌλ―Έν°μλ
org.intellij.lang.annotations.RegExpμ΄λ Έν μ΄μ μ΄ μ μ©λμ΄ μλ€. μ»΄νμΌλ¬μκ² λͺ¨λ λλ±ν Stringμ΄κ² μ§λ§, μ΄ μ΄λ Έν μ΄μ λλΆμ IDEμμλ μ κ· ννμμΌλ‘μμ λ¬Έμμ΄λ‘ μΈμλμ΄ μ»¨ν μ€νΈ μ‘μ μΌλ‘ μ κ·μ κ²μ¬λ₯Ό μΆμ²λ°μ μ μλ€.
2. ν΄λμ€μ μν
==1. ν¨ν΄ λ¬Έμμ΄, 2. νλκ·Έ μ€μ == κ°μ μ»΄νμΌν΄μ μ μ ν Matcherλ₯Ό λ§λλ κ²μ΄ μ£Όμ λͺ©μ μ΄λ€.
μ΄λ¬ν ν΄λμ€ λμμΈμ μ£Όμμμλ μ λλ¬λλ€.
- λ¬Έμμ΄λ‘ ꡬ체νλ μ κ· ννμμ λ¨Όμ μ΄ ν΄λμ€μ μΈμ€ν΄μ€λ‘ μ»΄νμΌλμ΄μΌ νλ€.
- 2κ°μ μ μΌν μ§λ ¬ν μμ: the pattern string and the flags
[!quote] Docs
/* * A regular expression, specified as a string, must first be compiled into an instance of this class. * * Pattern has only two serialized components: The pattern string * and the flags, which are all that is needed to recompile the pattern * when it is deserialized */
2-A. Matcher ν©ν 리
μ€μ§μ μΌλ‘ λ¬Έμμ΄μ λ°μ ν¨ν΄ λΉκ΅λ₯Ό μννλ κ²μ Matcherμ μν μ΄λ€. Matcher ν΄λμ€λ publicμΌλ‘ μ΄λ €μμ§λ§, μμ±μλ package-privateλ‘ κ΅¬μ±λ κ²μ 보면,
Patternμ μ κ· ννμ μ»΄νμΌλ‘ μ΄κΈ°νκ° νμν ==Matcherμ ν©ν 리 ν΄λμ€==λ‘ μ΄ν΄ν μ μλ€.
/*
* An engine that performs match operation on a java.lang.CharSequence character sequence by interpreting a Pattern.
*
* A matcher is created from a pattern by invoking the pattern's Patter#matcher matcher method. (...)
*/
public final class Matcher implements MatchResult {
Matcher() {} // No default constructor.
/**
* All matchers have the state used by Pattern during a match.
*/
Matcher(Pattern parent, CharSequence text) { ... )
3. Flags
νλκ·Έλ λμΌν λ¬Έλ²μ΄ νκ²½μ λ°λΌ λ€λ₯΄κ² λμν΄μΌ νλ λΆλΆλ€μ 컀λ²ν΄μ€λ€.
3-A. Pattern.DOTALL
μμμ λν μ€λͺ
μ 보면 line terminatorλΌλ μ©μ΄κ° λμ€λ κ²μ μ μ μλ€. ==μ€ λ°κΏ==μ μλ―Ένλ λ¬Έμλ€μ μ΄μΉνλ κ°λ
μΈλ°, LF, CRLF κ²°μ νλ κ²μ²λΌ μ€ λ°κΏμ νννλ λ¬Έμκ°
λ¬λΌμ§ μ μλ€λ κ²λ§ μ΄ν΄νλ©΄ λλ€.
μ κ· ννμμμ . (DOT)μ μμμ νλμ λ¬Έμμ λν νμμ΄μ§λ§, κΈ°λ³Έμ μΌλ‘ line terminatorλ μμΈλ‘ λλ€. DOTALLμ μ΄λ¬ν κΈ°λ³Έ λμμ μμ νμ¬, κ·ΈμΌλ§λ‘
_μ (DOT)μ΄ λͺ¨λ (ALL) λ¬Έμλ₯Ό λν_ν μ μλλ‘ μ€μ ν΄μ£ΌκΈ° μν μ»΄νμΌ μ΅μ
μ΄λ€.
^4b506c
3-A-1. LineTerminator μμ
[!quote] Definition A one- or two-character sequence that ==marks the end of a line== of the input character sequence.
'\n''\r'"\r\n"'\u0085''\u2028''\u2029'java.util.regex.Pattern#lt
Javaμ char μλ£νμ 2 Byteμ΄κΈ°μ λ¨μΌ 16 bit μ λμ½λκΉμ§λ ννν μ μλ€. λ°λΌμ,
"\r\n"λ₯Ό μ μΈν λͺ¨λ λ¬Έμκ° μμ λ°μ΄ν'λ‘ λ¬Άμ¬ μλ κ²μ μ°Έκ³ νμ.
Patternμ μ΄κΈ°ν ν λ, DOTALL νλκ·Έλ₯Ό μ€μ νλ κ²μ΄ μ€μ μ κ·μ λ§€μΉμ μ΄λ€ κ²°κ³Όλ‘ λνλλμ§ νμ΅ ν
μ€νΈλ₯Ό μ§νν΄λ³΄μ.
CASE 1: κΈ°λ³Έ DOT
λΆλͺ
.(DOT)μ μμμ λ¬Έμ νλλ₯Ό λννμ§λ§, line terminator λ¬Έμλ§μ μμΈλΌκ³ νλ€.
λ°λΌμ, μ΄ μνλ‘ μ€ννλ©΄ μΌλ°μ μΈ λ¬Έμ νλλ₯Ό ν¬ν¨ν 첫 λ²μ§Έ μΌμ΄μ€λ§ μ±κ³΅νλ€.
@ParameterizedTest
@ValueSource(strings = {" ", "\n", "\r", "\r\n", "\u0085", "\u2028", "\u2029"})
void matchLineTerminators(String lineTerminator) {
Pattern p = Pattern.compile(".");
Matcher m = p.matcher(lineTerminator);
assertTrue(m.matches());
assertEquals(lineTerminator, m.group());
}

CASE 2: DOTALL
νλκ·Έλ₯Ό μ€μ ν΄μ£Όλ©΄ λμΌν κ·μΉλ λ€λ₯΄κ² λμνλ€. DOTALL νλκ·Έλ .(DOT)μ΄ μμΈλ‘ λμλ line terminator λ¬Έμλ€λ νλμ λ¬Έμλ‘ μ·¨κΈνλλ‘ λ§λ λ€. λ€λ§, "." κ·μΉμ μ νν
νλμ λ¬Έμλ₯Ό λννκΈ°μ 2κ°μ λ¬Έμλ‘ κ΅¬μ±λ "\r\n" μΌμ΄μ€λ λ§€μΉλμ§ μλ κ²μ λ³Ό μ μλ€.
@ParameterizedTest
@ValueSource(strings = {" ", "\n", "\r", "\r\n", "\u0085", "\u2028", "\u2029"})
void matchLineTerminators(String lineTerminator) {
Pattern p = Pattern.compile(".", Pattern.DOTALL);
Matcher m = p.matcher(lineTerminator);
assertTrue(m.matches());
assertEquals(lineTerminator, m.group());
}

CASE 3: ".+" & DOTALL
+ κΈ°νΈλ νΉμ ν ν¨ν΄μ 1λ² μ΄μ λ°λ³΅λλ κ²½μ°λ‘ νμ₯μν¨λ€. μ΄λ₯Ό ν΅ν΄, 2κ°μ λ¬Έμλ‘ μ΄λ£¨μ΄μ§ "\r\n" μΌμ΄μ€λ ν
μ€νΈλ₯Ό ν΅κ³Όνκ² λλ€. μ°Έκ³ λ‘ ".{1,2}"μ κ°μ΄ λ°λ³΅ νμμ ννκ³Ό μνμ
λͺ
μνλ κ²λ κ°λ₯νλ€.
@ParameterizedTest
@ValueSource(strings = {" ", "\n", "\r", "\r\n", "\u0085", "\u2028", "\u2029"})
void matchLineTerminators(String lineTerminator) {
Pattern p = Pattern.compile(".+", Pattern.DOTALL);
Matcher m = p.matcher(lineTerminator);
assertTrue(m.matches());
assertEquals(lineTerminator, m.group());
}

CASE 4: ".+"
DOTALLμ΄ λΉ μ§λ©΄ λΉμ°νκ²λ κ²°κ³Όλ CASE 1κ³Ό λμΌν΄μ§λ€. (κ²°κ³Ό μλ΅)


