mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
String#match? and Symbol#match?
* string.c (rb_str_match_m_p): inverse of Regexp#match?. based on the patch by Herwin Weststrate <herwin@snt.utwente.nl>. [Fix GH-1483] [Feature #12898] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@57053 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
3f3fc0182e
commit
6dd5ee752a
4 changed files with 95 additions and 6 deletions
|
@ -1394,6 +1394,7 @@ VALUE rb_rational_cmp(VALUE self, VALUE other);
|
||||||
VALUE rb_reg_compile(VALUE str, int options, const char *sourcefile, int sourceline);
|
VALUE rb_reg_compile(VALUE str, int options, const char *sourcefile, int sourceline);
|
||||||
VALUE rb_reg_check_preprocess(VALUE);
|
VALUE rb_reg_check_preprocess(VALUE);
|
||||||
long rb_reg_search0(VALUE, VALUE, long, int, int);
|
long rb_reg_search0(VALUE, VALUE, long, int, int);
|
||||||
|
VALUE rb_reg_match_p(VALUE re, VALUE str, long pos);
|
||||||
void rb_backref_set_string(VALUE string, long pos, long len);
|
void rb_backref_set_string(VALUE string, long pos, long len);
|
||||||
int rb_match_count(VALUE match);
|
int rb_match_count(VALUE match);
|
||||||
int rb_match_nth_defined(int nth, VALUE match);
|
int rb_match_nth_defined(int nth, VALUE match);
|
||||||
|
|
15
re.c
15
re.c
|
@ -3225,19 +3225,22 @@ rb_reg_match_m(int argc, VALUE *argv, VALUE re)
|
||||||
static VALUE
|
static VALUE
|
||||||
rb_reg_match_m_p(int argc, VALUE *argv, VALUE re)
|
rb_reg_match_m_p(int argc, VALUE *argv, VALUE re)
|
||||||
{
|
{
|
||||||
VALUE str, initpos;
|
long pos = rb_check_arity(argc, 1, 2) > 1 ? NUM2LONG(argv[1]) : 0;
|
||||||
long pos = 0;
|
return rb_reg_match_p(re, argv[0], pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
VALUE
|
||||||
|
rb_reg_match_p(VALUE re, VALUE str, long pos)
|
||||||
|
{
|
||||||
regex_t *reg;
|
regex_t *reg;
|
||||||
onig_errmsg_buffer err = "";
|
onig_errmsg_buffer err = "";
|
||||||
OnigPosition result;
|
OnigPosition result;
|
||||||
const UChar *start, *end;
|
const UChar *start, *end;
|
||||||
int tmpreg;
|
int tmpreg;
|
||||||
|
|
||||||
rb_scan_args(argc, argv, "11", &str, &initpos);
|
|
||||||
if (NIL_P(str)) return Qfalse;
|
if (NIL_P(str)) return Qfalse;
|
||||||
str = SYMBOL_P(str) ? rb_sym2str(str) : rb_str_to_str(str);
|
str = SYMBOL_P(str) ? rb_sym2str(str) : StringValue(str);
|
||||||
if (argc == 2) {
|
if (pos) {
|
||||||
pos = NUM2LONG(initpos);
|
|
||||||
if (pos < 0) {
|
if (pos < 0) {
|
||||||
pos += NUM2LONG(rb_str_length(str));
|
pos += NUM2LONG(rb_str_length(str));
|
||||||
if (pos < 0) return Qfalse;
|
if (pos < 0) return Qfalse;
|
||||||
|
|
41
string.c
41
string.c
|
@ -3601,6 +3601,32 @@ rb_str_match_m(int argc, VALUE *argv, VALUE str)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* call-seq:
|
||||||
|
* str.match?(pattern) -> true or false
|
||||||
|
* str.match?(pattern, pos) -> true or false
|
||||||
|
*
|
||||||
|
* Converts _pattern_ to a +Regexp+ (if it isn't already one), then
|
||||||
|
* returns a +true+ or +false+ indicates whether the regexp is
|
||||||
|
* matched _str_ or not without updating <code>$~</code> and other
|
||||||
|
* related variables. If the second parameter is present, it
|
||||||
|
* specifies the position in the string to begin the search.
|
||||||
|
*
|
||||||
|
* "Ruby".match?(/R.../) #=> true
|
||||||
|
* "Ruby".match?(/R.../, 1) #=> false
|
||||||
|
* "Ruby".match?(/P.../) #=> false
|
||||||
|
* $& #=> nil
|
||||||
|
*/
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
rb_str_match_m_p(int argc, VALUE *argv, VALUE str)
|
||||||
|
{
|
||||||
|
VALUE re;
|
||||||
|
rb_check_arity(argc, 1, 2);
|
||||||
|
re = get_pat(argv[0]);
|
||||||
|
return rb_reg_match_p(re, str, argc > 1 ? NUM2LONG(argv[1]) : 0);
|
||||||
|
}
|
||||||
|
|
||||||
enum neighbor_char {
|
enum neighbor_char {
|
||||||
NEIGHBOR_NOT_CHAR,
|
NEIGHBOR_NOT_CHAR,
|
||||||
NEIGHBOR_FOUND,
|
NEIGHBOR_FOUND,
|
||||||
|
@ -9738,6 +9764,19 @@ sym_match_m(int argc, VALUE *argv, VALUE sym)
|
||||||
return rb_str_match_m(argc, argv, rb_sym2str(sym));
|
return rb_str_match_m(argc, argv, rb_sym2str(sym));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* call-seq:
|
||||||
|
* sym.match?(obj) -> true or false
|
||||||
|
*
|
||||||
|
* Returns <code>sym.to_s.match?(obj)</code>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
sym_match_m_p(int argc, VALUE *argv, VALUE sym)
|
||||||
|
{
|
||||||
|
return rb_str_match_m_p(argc, argv, sym);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* sym[idx] -> char
|
* sym[idx] -> char
|
||||||
|
@ -9924,6 +9963,7 @@ Init_String(void)
|
||||||
rb_define_method(rb_cString, "empty?", rb_str_empty, 0);
|
rb_define_method(rb_cString, "empty?", rb_str_empty, 0);
|
||||||
rb_define_method(rb_cString, "=~", rb_str_match, 1);
|
rb_define_method(rb_cString, "=~", rb_str_match, 1);
|
||||||
rb_define_method(rb_cString, "match", rb_str_match_m, -1);
|
rb_define_method(rb_cString, "match", rb_str_match_m, -1);
|
||||||
|
rb_define_method(rb_cString, "match?", rb_str_match_m_p, -1);
|
||||||
rb_define_method(rb_cString, "succ", rb_str_succ, 0);
|
rb_define_method(rb_cString, "succ", rb_str_succ, 0);
|
||||||
rb_define_method(rb_cString, "succ!", rb_str_succ_bang, 0);
|
rb_define_method(rb_cString, "succ!", rb_str_succ_bang, 0);
|
||||||
rb_define_method(rb_cString, "next", rb_str_succ, 0);
|
rb_define_method(rb_cString, "next", rb_str_succ, 0);
|
||||||
|
@ -10070,6 +10110,7 @@ Init_String(void)
|
||||||
rb_define_method(rb_cSymbol, "size", sym_length, 0);
|
rb_define_method(rb_cSymbol, "size", sym_length, 0);
|
||||||
rb_define_method(rb_cSymbol, "empty?", sym_empty, 0);
|
rb_define_method(rb_cSymbol, "empty?", sym_empty, 0);
|
||||||
rb_define_method(rb_cSymbol, "match", sym_match_m, -1);
|
rb_define_method(rb_cSymbol, "match", sym_match_m, -1);
|
||||||
|
rb_define_method(rb_cSymbol, "match?", sym_match_m_p, -1);
|
||||||
|
|
||||||
rb_define_method(rb_cSymbol, "upcase", sym_upcase, -1);
|
rb_define_method(rb_cSymbol, "upcase", sym_upcase, -1);
|
||||||
rb_define_method(rb_cSymbol, "downcase", sym_downcase, -1);
|
rb_define_method(rb_cSymbol, "downcase", sym_downcase, -1);
|
||||||
|
|
|
@ -2111,6 +2111,50 @@ CODE
|
||||||
assert_raise(ArgumentError) { "foo".match }
|
assert_raise(ArgumentError) { "foo".match }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_match_p_regexp
|
||||||
|
/backref/ =~ 'backref'
|
||||||
|
# must match here, but not in a separate method, e.g., assert_send,
|
||||||
|
# to check if $~ is affected or not.
|
||||||
|
assert_equal(true, "".match?(//))
|
||||||
|
assert_equal(true, :abc.match?(/.../))
|
||||||
|
assert_equal(true, 'abc'.match?(/b/))
|
||||||
|
assert_equal(true, 'abc'.match?(/b/, 1))
|
||||||
|
assert_equal(true, 'abc'.match?(/../, 1))
|
||||||
|
assert_equal(true, 'abc'.match?(/../, -2))
|
||||||
|
assert_equal(false, 'abc'.match?(/../, -4))
|
||||||
|
assert_equal(false, 'abc'.match?(/../, 4))
|
||||||
|
assert_equal(true, "\u3042xx".match?(/../, 1))
|
||||||
|
assert_equal(false, "\u3042x".match?(/../, 1))
|
||||||
|
assert_equal(true, ''.match?(/\z/))
|
||||||
|
assert_equal(true, 'abc'.match?(/\z/))
|
||||||
|
assert_equal(true, 'Ruby'.match?(/R.../))
|
||||||
|
assert_equal(false, 'Ruby'.match?(/R.../, 1))
|
||||||
|
assert_equal(false, 'Ruby'.match?(/P.../))
|
||||||
|
assert_equal('backref', $&)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_match_p_string
|
||||||
|
/backref/ =~ 'backref'
|
||||||
|
# must match here, but not in a separate method, e.g., assert_send,
|
||||||
|
# to check if $~ is affected or not.
|
||||||
|
assert_equal(true, "".match?(''))
|
||||||
|
assert_equal(true, :abc.match?('...'))
|
||||||
|
assert_equal(true, 'abc'.match?('b'))
|
||||||
|
assert_equal(true, 'abc'.match?('b', 1))
|
||||||
|
assert_equal(true, 'abc'.match?('..', 1))
|
||||||
|
assert_equal(true, 'abc'.match?('..', -2))
|
||||||
|
assert_equal(false, 'abc'.match?('..', -4))
|
||||||
|
assert_equal(false, 'abc'.match?('..', 4))
|
||||||
|
assert_equal(true, "\u3042xx".match?('..', 1))
|
||||||
|
assert_equal(false, "\u3042x".match?('..', 1))
|
||||||
|
assert_equal(true, ''.match?('\z'))
|
||||||
|
assert_equal(true, 'abc'.match?('\z'))
|
||||||
|
assert_equal(true, 'Ruby'.match?('R...'))
|
||||||
|
assert_equal(false, 'Ruby'.match?('R...', 1))
|
||||||
|
assert_equal(false, 'Ruby'.match?('P...'))
|
||||||
|
assert_equal('backref', $&)
|
||||||
|
end
|
||||||
|
|
||||||
def test_clear
|
def test_clear
|
||||||
s = "foo" * 100
|
s = "foo" * 100
|
||||||
s.clear
|
s.clear
|
||||||
|
|
Loading…
Reference in a new issue