정규 표현식(정규식)은 Elixir에서 문자열을 다룰 때 강력한 도구예요. Elixir의 정규 표현식은 PCRE 명세(Perl Compatible Regular Expressions)를 따라요. 정규 표현식의 의미를 나타내는 문자열 패턴은 먼저 컴파일된 다음, 문자열 전체 또는 일부를 일치시키는 데 사용돼요.
Elixir에서 정규 표현식을 만드는 가장 일반적인 방법은 ~r 시길을 사용하는 거예요. 시길은 Elixir에서 흔한 작업을 위한 편의 문법 단축 표현을 제공해요. 여기서는 ~r이 Regex.compile!/2를 사용하는 단축 표현이에요.
Regex.compile!("test") == ~r/test/
# => true
=~/2 연산자는 문자열에 정규식을 일치시켜 boolean 결과를 반환할 때 유용해요.
"this is a test" =~ ~r/test/
# => true
\로 이스케이프해야 해요. 예를 들어 ~r/\?/처럼요.\d, \w)를 쓰면 패턴이 특정 문자 범위와 일치하도록 할 수 있어요|)를 쓰면 패턴이 여러 패턴 중 하나와 일치하도록 할 수 있어요{N, M}, *, ?)를 쓰면 패턴이 지정한 횟수만큼 반복되는 패턴과 일치하도록 할 수 있어요())을 쓰면 패턴의 일부를 하나의 단위로 묶을 수 있어요정규 표현식은 문자열의 일부분을 추출할 때도 유용해요. 이를 _캡처_라고 해요. 문자열의 일부를 _캡처_하려면 캡처하고 싶은 부분에 그룹(())을 만들고 Regex.run을 사용해요.
Regex.run(~r/Weight: (\d*)g/, "Weight: 150g")
# => ["Weight: 150g", "150"]
캡처에는 번호가 매겨지고(1부터 시작해요), 정규 표현식으로 문자열의 일부를 바꿀 때 결과에서 사용할 수도 있어요:
Regex.replace(~r/Weight: (\d*)g/, "Weight: 150g", "Gewicht: \\1g")
# => "Gewicht: 150g"
여는 괄호 뒤에 ?<name>을 붙여 캡처에 이름을 지정할 수도 있어요. 이름이 있는 캡처를 담은 맵을 얻으려면 Regex.named_captures/3을 사용해요.
Regex.named_captures(~r/Weight: (?<weight>\d*)g/, "Weight: 150g")
# => %{"weight" => "150"}
정규 표현식 끝에 특수 플래그를 붙이면 정규 표현식의 동작을 바꿀 수 있어요. 예: ~r/test/i.
caseless i - 대소문자를 구분하지 않아요
"A" =~ ~r/a/
# => false
"A" =~ ~r/a/i
# => true
unicode u - \p 같은 유니코드 전용 패턴을 쓸 수 있게 하고, \w 같은 문자 클래스가 유니코드에서도 일치하도록 해요
"ö" =~ ~r/^\w$/
# => false
"ö" =~ ~r/^\w$/u
# => true
dotall, multiline, extended, firstline, ungreedy가 있어요~r 시길은 "pattern" |> Regex.escape() |> Regex.compile!()의 단축 표현이기 때문에, 문자열 보간을 사용해 정규 표현식 패턴을 동적으로 만들 수도 있어요:
anchor = "$"
regex = ~r/end of the line#{anchor}/
"end of the line?" =~ regex
# => false
"end of the line" =~ regex
# => true
String 모듈정규 표현식이 강력하긴 하지만, 항상 쓰는 게 좋은 건 아니에요:
일반적으로 가능하면 String 모듈의 함수를 사용하는 게 좋아요.
# Don't use regular expressions to check a suffix:
if "YELLING!" =~ ~r/!$/, do: "Whoa, chill out!"
# Use a string function:
if String.ends_with?("YELLING!", "!"), do: "Whoa, chill out!"