diff options
author | naruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2016-05-18 10:37:13 +0000 |
---|---|---|
committer | naruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2016-05-18 10:37:13 +0000 |
commit | f09574c879fe9a4488164a41b453617b4b1d56bb (patch) | |
tree | 4cde28960bec2ae35fa9a1c1c0d65900d940d8f3 | |
parent | 898aeb87792e952ba831931c2212baa50d81b62e (diff) |
* re.c (rb_reg_match_m_p): Introduce Regexp#match?, which returns
bool and doesn't save backref.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@55061 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | NEWS | 5 | ||||
-rw-r--r-- | re.c | 75 | ||||
-rw-r--r-- | test/ruby/test_regexp.rb | 13 |
4 files changed, 98 insertions, 0 deletions
@@ -1,3 +1,8 @@ +Wed May 18 19:33:54 2016 NARUSE, Yui <naruse@ruby-lang.org> + + * re.c (rb_reg_match_m_p): Introduce Regexp#match?, which returns + bool and doesn't save backref. + Wed May 18 16:52:03 2016 Kazuki Yamaguchi <k@rhe.jp> * ext/openssl/ossl_pkcs12.c (ossl_pkcs12_initialize): pop errors @@ -54,6 +54,11 @@ with all sufficient information, see the ChangeLog file or Redmine * Fixnum and Bignum are unified into Integer [Feature #12005] +* Regexp + + * Regexp#match? [Feature #8110] + This returns bool and doesn't save backref. + * String * String.new(capacity: size) [Feature #12024] @@ -3203,6 +3203,80 @@ rb_reg_match_m(int argc, VALUE *argv, VALUE re) } /* + * call-seq: + * rxp.match?(str) -> true or false + * rxp.match?(str,pos) -> true or false + * + * Returns a <code>true</code> or <code>false</code> indicates whether the + * regexp is matched or not without updating $~ and other related variables. + * If the second parameter is present, it specifies the position in the string + * to begin the search. + * + * /R.../.match?("Ruby") #=> true + * /R.../.match?("Ruby", 1) #=> true + * /P.../.match?("Ruby") #=> false + * $& #=> nil + */ + +static VALUE +rb_reg_match_m_p(int argc, VALUE *argv, VALUE re) +{ + VALUE str, initpos; + long pos = 0; + regex_t *reg; + onig_errmsg_buffer err = ""; + int result, tmpreg; + + rb_scan_args(argc, argv, "11", &str, &initpos); + if (NIL_P(str)) return Qnil; + str = SYMBOL_P(str) ? rb_sym2str(str) : rb_str_to_str(str); + if (argc == 2) { + pos = NUM2LONG(initpos); + if (pos == 0) goto run; + if (pos < 0) { + pos += NUM2LONG(rb_str_length(str)); + if (pos == 0) goto run; + if (pos < 0) return Qnil; + + } + pos = rb_str_offset(str, pos); + } +run: + if (pos >= RSTRING_LEN(str)) { + return Qnil; + } + reg = rb_reg_prepare_re0(re, str, err); + tmpreg = reg != RREGEXP_PTR(re); + if (!tmpreg) RREGEXP(re)->usecnt++; + result = onig_search(reg, + ((UChar*)RSTRING_PTR(str)), + ((UChar*)RSTRING_END(str)), + ((UChar*)(RSTRING_PTR(str)) + pos), + ((UChar*)RSTRING_PTR(str)), + NULL, ONIG_OPTION_NONE); + if (!tmpreg) RREGEXP(re)->usecnt--; + if (tmpreg) { + if (RREGEXP(re)->usecnt) { + onig_free(reg); + } + else { + onig_free(RREGEXP_PTR(re)); + RREGEXP_PTR(re) = reg; + } + } + if (result < 0) { + if (result == ONIG_MISMATCH) { + return Qfalse; + } + else { + onig_error_code_to_str((UChar*)err, (int)result); + rb_reg_raise(RREGEXP_SRC_PTR(re), RREGEXP_SRC_LEN(re), err, re); + } + } + return Qtrue; +} + +/* * Document-method: compile * * Alias for <code>Regexp.new</code> @@ -3865,6 +3939,7 @@ Init_Regexp(void) rb_define_method(rb_cRegexp, "===", rb_reg_eqq, 1); rb_define_method(rb_cRegexp, "~", rb_reg_match2, 0); rb_define_method(rb_cRegexp, "match", rb_reg_match_m, -1); + rb_define_method(rb_cRegexp, "match?", rb_reg_match_m_p, -1); rb_define_method(rb_cRegexp, "to_s", rb_reg_to_s, 0); rb_define_method(rb_cRegexp, "inspect", rb_reg_inspect, 0); rb_define_method(rb_cRegexp, "source", rb_reg_source, 0); diff --git a/test/ruby/test_regexp.rb b/test/ruby/test_regexp.rb index 0562785199..4d534114da 100644 --- a/test/ruby/test_regexp.rb +++ b/test/ruby/test_regexp.rb @@ -526,6 +526,19 @@ class TestRegexp < Test::Unit::TestCase $_ = nil; assert_nil(~/./) end + def test_match_p + /backref/ =~ 'backref' + assert_nil(//.match?(nil)) + assert_equal(true, /.../.match?(:abc)) + assert_raise(TypeError) { /.../.match?(Object.new) } + assert_equal(true, /../.match?('abc', 1)) + assert_equal(true, /../.match?('abc', -2)) + assert_nil(/../.match?("abc", -4)) + assert_nil(/../.match?("abc", 4)) + assert_equal(true, /../n.match?("\u3042" + '\x', 1)) + assert_equal('backref', $&) + end + def test_eqq assert_equal(false, /../ === nil) end |