raku-type-match
class Match is Capture is Cool does NQPMatchRole {}
Match 객체는 성공한 정규식 매치의 결과예요. 너비가 0인(zero-width) 매치까지 포함하죠. 원본 문자열(.orig)과, 위치·이름 붙은 캡처, 원본 문자열 안에서 매치가 시작·끝나는 위치, 그리고 **AST(추상 구문 트리)**라고 부르는 페이로드를 저장해요. 이 AST는 복잡한 정규식·문법으로부터 데이터 구조를 만드는 데 쓰여요.
마지막 매치는 $¢라는 Match 객체에도 저장돼요. $¢는 정규식에 레시컬 스코프되는데, 다시 말해 정규식 안에서만 접근할 수 있어요.
my $c;
'abc' ~~ /.$${ $c = $¢ }/;
say $c; # OUTPUT: «「c」»
이 예시에서는 매치가 일어날 때 중괄호 안의 코드를 실행해요. 여기서는 문자열의 마지막 글자(실제로는 $가 두 번 와서 "마지막"을 가리키는)가 실행 시점이죠. $c는 커서 $¢의 값을 받는데, $¢는 그 Match를 담고 있어요. say로 쓸 때 Match는 .Str 호출을 통해 문자열로 바뀌죠. 이 $¢가 정규식 안에서 Match를 잡아낼 방법을 주는데, 정규식 밖에서는 $/을 써야 해요.
my $c; 'camelia' ~~ /<[ l m ]> {$c = $¢}/;
say $c; # OUTPUT: «「m」»
say $/; # OUTPUT: «「m」»
참고: 이 기능은 Raku 2018.02 릴리스부터 동작해요. 그 이전 버전에서는 Nil을 돌려줬을 거예요. 그리고 그 이전 버전에서는 정규식 안에서 같은 값을 갖는 $/을 대신 쓸 수 있었어요.
'123' ~~ / (\d) { say $0; say $/; } \d+ /; # OUTPUT: «「1」「1」 0 => 「1」»
$/과 $¢의 주된 차이는 스코프예요. 후자는 정규식 안에서만 값을 가져요.
'123' ~~ / (\d) { say $/; say $¢; } \d+ /; # OUTPUT: «「1」 0 => 「1」「1」 0 => 「1」»
say "¢ → ", $¢, "/ is $/"; ; # OUTPUT: «¢ → Nil/ is 123»
하위 매치(submatch)도 Match 객체예요. (해당 정규식이 수량화되었다면 Match 객체들의 목록이 되죠.) 그래서 각 매치 객체는 매치 객체 트리의 루트로 볼 수 있어요.
Match 객체는 진행 중인 매치(문법 엔진이 실행되는 동안)의 결과도 담을 수 있는데, 그 경우 pos 메서드가 현재 위치를 돌려줘요. 이 관점은 정규식 안에서 코드를 호출할 때만 보여요.
참고(사용 중단됨): 이 클래스에는 Cursor라는 동의어가 있었어요.
my constant Cursor = Match
처음에는 정규식 매치에서 초기 위치를 추적하는 데 쓰였지만, 현재 버전에서는 Match의 별칭이에요.
Methods
method pos
진행 중인 정규식 매치에서 Match.target에 대한 문자열 인덱스로 현재 위치를 돌려줘요.
my $a = 'abcdef';
$a ~~ /b. {say $/.pos }../; # OUTPUT: «3»
완료된 Match에는 이 메서드를 쓰지 않는 게 좋아요. 출력이 구현에 따라 달라질 수 있고, 어쨌든 명세되지 않았거든요.
method target
method target()
정규식이 매치하는 대상 객체의 문자열 표현을 돌려줘요. 정규식 엔진이 내부적으로 다루는 값이에요.
my $a = "þor" ~~ /o/;
say $a.target # OUTPUT: «þor»
method chars
method chars()
매치된 문자열의 문자 수를 돌려줘요. 매치가 없었다면 0을 돌려줘요. .Str.chars와 같은 값을 돌려주죠.
method clone
method clone()
Match 객체를 복제해요.
method orig
method orig()
정규식 엔진에 들어간 원본 입력을 돌려줘요. 보통은 문자열이지만 꼭 그럴 필요는 없어요. (문자열로 강제 변환될 수 있는 것이면 뭐든 가능해요.)
42 ~~ /.+/;
say $/.orig; # OUTPUT: «42»
say $/.orig.^name; # OUTPUT: «Int»
항상 문자열을 돌려주는 근사한 대안으로는 target 메서드를 보면 돼요.
method from
method from()
매치가 시작되는 위치의 인덱스를 돌려줘요.
method to
method to()
매치의 끝 바로 다음 위치의 인덱스를 돌려줘요. 매치의 끝이 음수라면 매치 위치를 돌려주고, 매치가 없었다면 Nil을 돌려줘요.
method made
method made()
make로 설정한 페이로드를 돌려줘요.
routine make
method make(Match:D: Mu $payload)
sub make(Mu $payload)
.ast 속성을 설정하며, 그 값은 .made로 꺼내 써요.
$/.make("your payload here");
즉 임의의 페이로드를 Match 객체에 저장해서 나중에 .made 메서드로 꺼내는 거예요. sub 형식은 기본적으로 $/에 대해 동작하므로 위 예시는 아래와 같아요.
make("your payload here");
이건 주로 문법의 액션스 클래스 메서드에서 쓰여요. 한 메서드가 데이터를 저장하고, 나중에 다른 메서드가 그걸 꺼내죠. 어떤 데이터를 저장할지는 여러분 몫이에요. 트리 노드, 계산 결과, 타입 객체, 값 목록 등 무엇이든 될 수 있어요.
sub 형식은 현재 Match인 $/에 동작해서 편리한 단축이 돼요.
method my-action ($/) {
make "foo: $/";
}
method actions
method actions(Match:D: --> Mu)
이 Match 객체를 만드는 데 사용된 문법이 쓴 액션스 객체를 돌려줘요. 설정된 게 없다면 Mu를 돌려줘요.
method ast
made 메서드의 별칭이에요.
method Bool
method Bool(Capture:D: --> Bool:D)
성공한 매치면 True를, 실패한 매치면 False를 돌려줘요. 너비 0인 매치도 성공할 수 있다는 점을 기억해 두세요.
say 'abc' ~~ /^/; # OUTPUT: «「」»
say $/.from, ' ', $/.to, ' ', ?$/; # OUTPUT: «0 0 True»
method Str
method Str(Match:D: --> Str:D)
매치된 텍스트를 돌려줘요.
"abc123def" ~~ /\d+/;
say $/.Str; # OUTPUT: «123»
method Int
method Int(Match:D: --> Int:D)
매치된 텍스트의 문자열화된 결과를 Int로 변환하려 시도해요.
say ('12345' ~~ /234/).Int; # OUTPUT: «234»
say ('12345' ~~ /234/).Int.^name; # OUTPUT: «Int»
# the next line produces a warning about using Nil (result of a no match) in numeric context
say ('one-two' ~~ /234/).Int; # OUTPUT: «0» # because Nil.Int returns 0
method caps
인덱스 또는 하위 매치 이름을 키로, 하위 매치를 값으로 하는 페어들의 목록을 돌려줘요. 목록은 하위 매치의 시작 위치 순으로 정렬돼요.
method chunks
인덱스 또는 하위 매치 이름을 키로, 하위 매치를 값으로 하는 페어들의 목록을 돌려줘요. 목록은 하위 매치의 시작 위치 순으로 정렬돼요. 하위 매치로 매치되지 않은 문자열 부분은 ~ 문자열을 키로 하여 다른 페어들 사이에 끼워져요.
method list
위치 하위 매치들의 목록을 돌려줘요.
method hash
이름 붙은 하위 매치들의 해시를 돌려줘요.
method prematch
method prematch(Match:D: --> Str:D)
원본 문자열에서 매치 앞부분(leading up to the match)을 돌려줘요.
'abcdefg' ~~ /cd/;
say $/.prematch; # OUTPUT: «ab»
# will return a list of three match objects
"abc123def" ~~ m:g/\d/;
say $/.[1].prematch; # OUTPUT: «abc1»
method postmatch
method postmatch(Match:D: --> Str:D)
원본 문자열에서 매치 뒷부분(following the match)을 돌려줘요.
'abcdefg' ~~ /cd/;
say $/.postmatch; # OUTPUT: «efg»
# will return a list of three match objects
"abc123def" ~~ m:g/\d/;
say $/.[1].postmatch; # OUTPUT: «3def»
method replace-with
multi method replace-with(Match:D: Str() $replacement --> Str:D)
Match 객체를 $replacement로 바꾼 호출자(invocant) 문자열을 돌려줘요.
my Str $some-string = "Some foo";
my Match $match = $some-string.match(/foo/);
my $another-string = $match.replace-with("string"); # «Some string»
infix eqv
multi infix:<eqv>(Match:D \a, Match:D \b)
a와 b의 pos, from, orig 속성이 같고, made와 Capture::list, Capture::hash가 서로 같거나 둘 다 정의되지 않았다면 True를 돌려줘요.