Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby: Why does equals sign in literal regexp cause parsing error?

These parse and execute fine:

"=".scan(/=/)
"=".scan (/=/)

This causes "unterminated regexp meets end of file":

"=".scan /=/

If I insert something before the = the error goes away:

"=".scan /^=/

What's going on?

like image 850
Kelvin Avatar asked Oct 09 '12 16:10

Kelvin


People also ask

What does =~ mean in Ruby regex?

=~ is Ruby's basic pattern-matching operator. When one operand is a regular expression and the other is a string then the regular expression is used as a pattern to match against the string. (This operator is equivalently defined by Regexp and String so the order of String and Regexp do not matter.

What method should you use when you want to get all sequences matching a regex pattern in a string?

To find all the matching strings, use String's scan method.

How do you match a string in Ruby?

Ruby | Regexp match() functionRegexp#match() : force_encoding?() is a Regexp class method which matches the regular expression with the string and specifies the position in the string to begin the search. Return: regular expression with the string after matching it.

When should I use regex?

Regular expressions are useful in search and replace operations. The typical use case is to look for a sub-string that matches a pattern and replace it with something else. Most APIs using regular expressions allow you to reference capture groups from the search pattern in the replacement string.


1 Answers

I'm guessing that you're hitting this in the parser:

case '/':
    if (IS_BEG()) {
        lex_strterm = NEW_STRTERM(str_regexp, '/', 0);
        return tREGEXP_BEG;
    }
    if ((c = nextc()) == '=') {
        set_yylval_id('/');
        lex_state = EXPR_BEG;
        return tOP_ASGN;
    }

Note the nextc() check in the second if. For reference, tOP_ASGN is:

%token <id> tOP_ASGN    /* +=, -=  etc. */

so it is used for operator-assign tokens.

This suggests that that /=/ in

'='.scan /=/

is being seen as the divide-assign operator (/=) followed by a start-regex-literal (/).

You'll have trouble (of a slightly different sort) with this:

' ='.scan / =/

but not this:

' ='.scan(/ =/)

There is often ambiguity when a method call doesn't have parentheses. In this case, I think operator precedence rules apply and that's not what you're expecting.

I tend to put parentheses on all my method calls because I'm too old and cranky to want to worry about how the parser is going to behave.

like image 95
mu is too short Avatar answered Sep 27 '22 21:09

mu is too short