MatchData
MatchData
MatchData는 문자열에 Regexp를 매칭한 결과를 담는 객체예요. Regexp#match와 String#match가 돌려주고, Regexp.last_match가 돌려주는 전역 변수에도 저장돼요.
출처: Ruby 3.3 API
본문
사용 예시를 볼게요.
url = 'https://docs.ruby-lang.org/en/2.5.0/MatchData.html'
m = url.match(/(\d\.?)+/) # => #<MatchData "2.5.0" 1:"0">
m.string # => "https://docs.ruby-lang.org/en/2.5.0/MatchData.html"
m.regexp # => /(\d\.?)+/
# entire matched substring:
m[0] # => "2.5.0"
# Working with unnamed captures
m = url.match(%r{([^/]+)/([^/]+)\.html$})
m.captures # => ["2.5.0", "MatchData"]
m[1] # => "2.5.0"
m.values_at(1, 2) # => ["2.5.0", "MatchData"]
# Working with named captures
m = url.match(%r{(?<version>[^/]+)/(?<module>[^/]+)\.html$})
m.captures # => ["2.5.0", "MatchData"]
m.named_captures # => {"version"=>"2.5.0", "module"=>"MatchData"}
m[:version] # => "2.5.0"
m.values_at(:version, :module)
# => ["2.5.0", "MatchData"]
# Numerical indexes are working, too
m[1] # => "2.5.0"
m.values_at(1, 2) # => ["2.5.0", "MatchData"]
전역 변수와의 대응 (Global variables equivalence)
마지막 MatchData(Regexp.last_match가 돌려주는)의 각 부분은 전역 변수로도 별칭이 돼요.
$~는Regexp.last_match예요.$&는Regexp.last_match[ 0 ]이에요.$1,$2, ... 는Regexp.last_match[ i ](번호로 캡처)예요.$`는Regexp.last_match.pre_match예요.$'는Regexp.last_match.post_match예요.$+는Regexp.last_match[ -1 ](마지막 캡처)이에요.
Regexp 문서의 "Special global variables" 섹션도 함께 보세요.
Public Instance Methods
matchdata == object → true or false
object가 또 다른 MatchData 객체이고, 대상 문자열·regexp·매치·캡처가 self와 모두 같으면 true, 그렇지 않으면 false를 돌려줘요. (eql?의 별칭)
matchdata[index] → string or nil, matchdata[start, length] → array, matchdata[range] → array, matchdata[name] → string or nil
인자 index, start와 length, 또는 range가 주어지면 Array#[] 방식으로 매치와 캡처를 돌려줘요.
m = /(.)(.)(\d+)(\d)/.match("THX1138.")
# => #<MatchData "HX1138" 1:"H" 2:"X" 3:"113" 4:"8">
m[0] # => "HX1138"
m[1, 2] # => ["H", "X"]
m[1..3] # => ["H", "X", "113"]
m[-3, 2] # => ["X", "113"]
문자열이나 심볼 인자 name이 주어지면, 해당 이름에 대응하는 매치된 부분 문자열을 돌려줘요.
m = /(?<foo>.)(.)(?<bar>.+)/.match("hoge")
# => #<MatchData "hoge" foo:"h" bar:"ge">
m['foo'] # => "h"
m[:bar] # => "ge"
여러 캡처가 같은 이름이면, 마지막으로 매치된 부분 문자열을 돌려줘요.
m = /(?<foo>.)(?<foo>.+)/.match("hoge")
# => #<MatchData "hoge" foo:"h" foo:"oge">
m[:foo] #=> "oge"
m = /\W(?<foo>.+)|\w(?<foo>.+)|(?<foo>.+)/.match("hoge")
#<MatchData "hoge" foo:nil foo:"oge" foo:nil>
m[:foo] #=> "oge"
begin(n) → integer, begin(name) → integer
지정한 매치의 시작 오프셋(문자 단위)을 돌려줘요.
음이 아닌 정수 인자 n이 주어지면 n번째 매치의 시작 오프셋을 돌려줘요.
m = /(.)(.)(\d+)(\d)/.match("THX1138.")
# => #<MatchData "HX1138" 1:"H" 2:"X" 3:"113" 4:"8">
m[0] # => "HX1138"
m.begin(0) # => 1
m[3] # => "113"
m.begin(3) # => 3
m = /(т)(е)(с)/.match('тест')
# => #<MatchData "тес" 1:"т" 2:"е" 3:"с">
m[0] # => "тес"
m.begin(0) # => 0
m[3] # => "с"
m.begin(3) # => 2
문자열이나 심볼 인자 name이 주어지면 이름 붙은 매치의 시작 오프셋을 돌려줘요.
m = /(?<foo>.)(.)(?<bar>.)/.match("hoge")
# => #<MatchData "hog" foo:"h" bar:"g">
m.begin('foo') # => 0
m.begin(:bar) # => 2
관련: MatchData#end, MatchData#offset, MatchData#byteoffset.
byteoffset(n) → array
n번째 매치의 바이트 기반 시작·끝 오프셋을 담은 두 요소 배열을 돌려줘요. n은 이름 붙은 캡처를 가리키는 문자열이나 심볼일 수도 있어요.
m = /(.)(.)(\d+)(\d)/.match("THX1138.")
m.byteoffset(0) #=> [1, 7]
m.byteoffset(4) #=> [6, 7]
m = /(?<foo>.)(.)(?<bar>.)/.match("hoge")
p m.byteoffset(:foo) #=> [0, 1]
p m.byteoffset(:bar) #=> [2, 3]
captures → array
캡처 배열을 돌려줘요. m[0]을 제외한 모든 매치예요. (deconstruct로도 별칭돼 있어요.)
m = /(.)(.)(\d+)(\d)/.match("THX1138.")
# => #<MatchData "HX1138" 1:"H" 2:"X" 3:"113" 4:"8">
m[0] # => "HX1138"
m.captures # => ["H", "X", "113", "8"]
관련: MatchData.to_a.
deconstruct_keys(array_of_names) → hash
주어진 이름들에 대한 이름 붙은 캡처들의 해시를 돌려줘요.
m = /(?<hours>\d{2}):(?<minutes>\d{2}):(?<seconds>\d{2})/.match("18:37:22")
m.deconstruct_keys([:hours, :minutes]) # => {:hours => "18", :minutes => "37"}
m.deconstruct_keys(nil) # => {:hours => "18", :minutes => "37", :seconds => "22"}
이름 붙은 캡처가 정의되지 않았다면 빈 해시를 돌려줘요.
m = /(\d{2}):(\d{2}):(\d{2})/.match("18:37:22")
m.deconstruct_keys(nil) # => {}
end(n) → integer, end(name) → integer
지정한 매치의 끝 오프셋(문자 단위)을 돌려줘요.
음이 아닌 정수 인자 n이 주어지면 n번째 매치의 끝 오프셋을 돌려줘요.
m = /(.)(.)(\d+)(\d)/.match("THX1138.")
# => #<MatchData "HX1138" 1:"H" 2:"X" 3:"113" 4:"8">
m[0] # => "HX1138"
m.end(0) # => 7
m[3] # => "113"
m.end(3) # => 6
m = /(т)(е)(с)/.match('тест')
# => #<MatchData "тес" 1:"т" 2:"е" 3:"с">
m[0] # => "тес"
m.end(0) # => 3
m[3] # => "с"
m.end(3) # => 3
문자열이나 심볼 인자 name이 주어지면 이름 붙은 매치의 끝 오프셋을 돌려줘요.
m = /(?<foo>.)(.)(?<bar>.)/.match("hoge")
# => #<MatchData "hog" foo:"h" bar:"g">
m.end('foo') # => 1
m.end(:bar) # => 3
관련: MatchData#begin, MatchData#offset, MatchData#byteoffset.
eql?
==로도 별칭돼 있어요.
hash → integer
대상 문자열·regexp·매치·캡처를 기반으로 self의 정수 해시 값을 돌려줘요. Object#hash도 함께 보세요.
inspect → string
self의 문자열 표현을 돌려줘요.
m = /.$/.match("foo")
# => #<MatchData "o">
m.inspect # => "#<MatchData \"o\">"
m = /(.)(.)(.)/.match("foo")
# => #<MatchData "foo" 1:"f" 2:"o" 3:"o">
m = /(.)(.)?(.)/.match("fo")
# => #<MatchData "fo" 1:"f" 2:nil 3:"o">
m.inspect # => "#<MatchData \"fo\" 1:\"f\" 2:nil 3:\"o\">"
관련: MatchData#to_s.
length
size의 별칭이에요.
match(n) → string or nil, match(name) → string or nil
주어진 인자에 대응하는 매치된 부분 문자열을 돌려줘요.
음이 아닌 인자 n이 주어지면 n번째 매치의 부분 문자열을 돌려줘요.
m = /(.)(.)(\d+)(\d)(\w)?/.match("THX1138.")
# => #<MatchData "HX1138" 1:"H" 2:"X" 3:"113" 4:"8" 5:nil>
m.match(0) # => "HX1138"
m.match(4) # => "8"
m.match(5) # => nil
문자열이나 심볼 인자 name이 주어지면 이름 붙은 매치의 부분 문자열을 돌려줘요.
m = /(?<foo>.)(.)(?<bar>.+)/.match("hoge")
# => #<MatchData "hoge" foo:"h" bar:"ge">
m.match('foo') # => "h"
m.match(:bar) # => "ge"
match_length(n) → integer or nil, match_length(name) → integer or nil
주어진 인자에 대응하는 매치된 부분 문자열의 길이(문자 단위)를 돌려줘요.
음이 아닌 인자 n이 주어지면 n번째 매치의 부분 문자열 길이를 돌려줘요.
m = /(.)(.)(\d+)(\d)(\w)?/.match("THX1138.")
# => #<MatchData "HX1138" 1:"H" 2:"X" 3:"113" 4:"8" 5:nil>
m.match_length(0) # => 6
m.match_length(4) # => 1
m.match_length(5) # => nil
named_captures(symbolize_names: false) → hash
이름 붙은 캡처들의 해시를 돌려줘요. 각 키는 캡처 이름, 각 값은 캡처된 문자열이거나 nil이에요.
m = /(?<foo>.)(.)(?<bar>.+)/.match("hoge")
# => #<MatchData "hoge" foo:"h" bar:"ge">
m.named_captures # => {"foo"=>"h", "bar"=>"ge"}
m = /(?<a>.)(?<a>.)/.match("01")
# => #<MatchData "01" a:"0" a:"1">
m.named_captures #=> {"a" => "1"}
키워드 인자 symbolize_names에 참(true) 값을 주면, 결과 해시의 키가 Symbol이 돼요.
m = /(?<a>.)(?<a>.)/.match("01")
# => #<MatchData "01" a:"0" a:"1">
m.named_captures(symbolize_names: true) #=> {:a => "1"}
names → array_of_names
캡처 이름들의 배열을 돌려줘요 (Named Captures 참고).
m = /(?<foo>.)(?<bar>.)(?<baz>.)/.match("hoge")
# => #<MatchData "hog" foo:"h" bar:"o" baz:"g">
m.names # => ["foo", "bar", "baz"]
m = /foo/.match('foo') # => #<MatchData "foo">
m.names # => [] # No named captures.
다음과 동일해요.
m = /(?<foo>.)(?<bar>.)(?<baz>.)/.match("hoge")
m.regexp.names # => ["foo", "bar", "baz"]
offset(n) → [start_offset, end_offset], offset(name) → [start_offset, end_offset]
지정한 매치의 시작·끝 오프셋(문자 단위)을 담은 두 요소 배열을 돌려줘요.
m = /(.)(.)(\d+)(\d)/.match("THX1138.")
# => #<MatchData "HX1138" 1:"H" 2:"X" 3:"113" 4:"8">
m.offset(0) # => [1, 7]
m.offset(3) # => [3, 6]
m = /(?<foo>.)(.)(?<bar>.)/.match("hoge")
m.offset('foo') # => [0, 1]
m.offset(:bar) # => [2, 3]
관련: MatchData#byteoffset, MatchData#begin, MatchData#end.
post_match → str
대상 문자열에서 self의 첫 번째 매치(self[0])의 끝부터 문자열 끝까지의 부분 문자열을 돌려줘요. 정규식 전역 변수 $'와 동일해요.
m = /(.)(.)(\d+)(\d)/.match("THX1138: The Movie")
# => #<MatchData "HX1138" 1:"H" 2:"X" 3:"113" 4:"8">
m.post_match # => ": The Movie"
관련: MatchData.pre_match.
pre_match → string
대상 문자열의 처음부터 self의 첫 번째 매치(self[0])까지의 부분 문자열을 돌려줘요. 정규식 전역 변수 $`와 동일해요.
m = /(.)(.)(\d+)(\d)/.match("THX1138.")
# => #<MatchData "HX1138" 1:"H" 2:"X" 3:"113" 4:"8">
m.pre_match # => "T"
관련: MatchData#post_match.
regexp → regexp
매치를 만든 정규식을 돌려줘요.
m = /a.*b/.match("abc") # => #<MatchData "ab">
m.regexp # => /a.*b/
size → integer
매치 배열의 크기를 돌려줘요. (length로도 별칭돼 있어요.)
m = /(.)(.)(\d+)(\d)/.match("THX1138.")
# => #<MatchData "HX1138" 1:"H" 2:"X" 3:"113" 4:"8">
m.size # => 5
string → string
대상 문자열이 이미 동결(frozen)되어 있다면 그대로, 그렇지 않으면 대상 문자열의 동결된 복사본을 돌려줘요.
m = /(.)(.)(\d+)(\d)/.match("THX1138.")
m.string # => "THX1138."
to_a → array
매치 배열을 돌려줘요.
m = /(.)(.)(\d+)(\d)/.match("THX1138.")
# => #<MatchData "HX1138" 1:"H" 2:"X" 3:"113" 4:"8">
m.to_a # => ["HX1138", "H", "X", "113", "8"]
관련: MatchData#captures.
to_s → string
매치된 문자열을 돌려줘요.
m = /(.)(.)(\d+)(\d)/.match("THX1138.")
# => #<MatchData "HX1138" 1:"H" 2:"X" 3:"113" 4:"8">
m.to_s # => "HX1138"
관련: MatchData.inspect.
values_at(*indexes) → array
주어진 indexes에서의 매치와 캡처를 돌려줘요. indexes에는 다음이 섞여 올 수 있어요.
- 정수 (Integers)
- 범위 (Ranges)
- 이름 (문자열과 심볼)
m = /(.)(.)(\d+)(\d)/.match("THX1138: The Movie")
# => #<MatchData "HX1138" 1:"H" 2:"X" 3:"113" 4:"8">
m.values_at(0, 2, -2) # => ["HX1138", "X", "113"]
m.values_at(1..2, -1) # => ["H", "X", "8"]
m = /(?<a>\d+) *(?<op>[+\-*\/]) *(?<b>\d+)/.match("1 + 2")
# => #<MatchData "1 + 2" a:"1" op:"+" b:"2">
m.values_at(0, 1..2, :a, :b, :op)
# => ["1 + 2", "1", "+", "1", "2", "+"]
더 알아보기
- 정규식과 전역 변수에 대한 더 자세한 내용은
Regexp문서를 보세요. - 매칭을 시작하는
Regexp#match,String#match,Regexp.last_match도 함께 확인하세요.