summaryrefslogtreecommitdiff
path: root/re.c
diff options
context:
space:
mode:
authorShugo Maeda <shugo@ruby-lang.org>2022-02-19 19:10:00 +0900
committerGitHub <noreply@github.com>2022-02-19 19:10:00 +0900
commitc8817d6a3ebc9bbc151625bca198b8f327d1d68f (patch)
tree8e147d1ec055f668f123a87fd979946206fd2ee4 /re.c
parentdb6b23c76cbc7888cd9a9912790c2068703afdd0 (diff)
Add String#byteindex, String#byterindex, and MatchData#byteoffset (#5518)
* Add String#byteindex, String#byterindex, and MatchData#byteoffset [Feature #13110] Co-authored-by: NARUSE, Yui <naruse@airemix.jp>
Notes
Notes: Merged-By: shugo <shugo@ruby-lang.org>
Diffstat (limited to 're.c')
-rw-r--r--re.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/re.c b/re.c
index 66519effcd..9c1adbb0ff 100644
--- a/re.c
+++ b/re.c
@@ -1234,6 +1234,38 @@ match_offset(VALUE match, VALUE n)
LONG2NUM(RMATCH(match)->rmatch->char_offset[i].end));
}
+/*
+ * call-seq:
+ * mtch.byteoffset(n) -> array
+ *
+ * Returns a two-element array containing the beginning and ending byte-based offsets of
+ * the <em>n</em>th match.
+ * <em>n</em> can be a string or symbol to reference a named capture.
+ *
+ * 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]
+ *
+ */
+
+static VALUE
+match_byteoffset(VALUE match, VALUE n)
+{
+ int i = match_backref_number(match, n);
+ struct re_registers *regs = RMATCH_REGS(match);
+
+ match_check(match);
+ backref_number_check(regs, i);
+
+ if (BEG(i) < 0)
+ return rb_assoc_new(Qnil, Qnil);
+ return rb_assoc_new(LONG2NUM(BEG(i)), LONG2NUM(END(i)));
+}
+
/*
* call-seq:
@@ -4162,6 +4194,7 @@ Init_Regexp(void)
rb_define_method(rb_cMatch, "size", match_size, 0);
rb_define_method(rb_cMatch, "length", match_size, 0);
rb_define_method(rb_cMatch, "offset", match_offset, 1);
+ rb_define_method(rb_cMatch, "byteoffset", match_byteoffset, 1);
rb_define_method(rb_cMatch, "begin", match_begin, 1);
rb_define_method(rb_cMatch, "end", match_end, 1);
rb_define_method(rb_cMatch, "match", match_nth, 1);