Ruby Regular Expression Using Variable Name

Ruby regular expression using variable name

The code you think doesn't work, does:

var = "Value"
str = "a test Value"
p str.gsub( /#{var}/, 'foo' ) # => "a test foo"

Things get more interesting if var can contain regular expression meta-characters. If it does and you want those matacharacters to do what they usually do in a regular expression, then the same gsub will work:

var = "Value|a|test"
str = "a test Value"
str.gsub( /#{var}/, 'foo' ) # => "foo foo foo"

However, if your search string contains metacharacters and you do not want them interpreted as metacharacters, then use Regexp.escape like this:

var = "*This*"
str = "*This* is a string"
p str.gsub( /#{Regexp.escape(var)}/, 'foo' )
# => "foo is a string"

Or just give gsub a string instead of a regular expression. In MRI >= 1.8.7, gsub will treat a string replacement argument as a plain string, not a regular expression:

var = "*This*"
str = "*This* is a string"
p str.gsub(var, 'foo' ) # => "foo is a string"

(It used to be that a string replacement argument to gsub was automatically converted to a regular expression. I know it was that way in 1.6. I don't recall which version introduced the change).

As noted in other answers, you can use Regexp.new as an alternative to interpolation:

var = "*This*"
str = "*This* is a string"
p str.gsub(Regexp.new(Regexp.escape(var)), 'foo' )
# => "foo is a string"

Regex that matches valid Ruby local variable names

Identifiers are pretty straightforward. They begin with letters or an underscore, and contain letters, underscore and numbers. Local variables can't (or shouldn't?) begin with an uppercase letter, so you could just use a regex like this.

/^[a-z_][a-zA-Z_0-9]*$/

How do you use Match/Regular Expression with a variable in Ruby?

Regex literal already accepts interpolation. Just do

match = string.match(/\A>.*\(#{number}\)/)

regular expression and special variable in Ruby

$1 refers to a numbered capture group

#{$1} would be referring to a named capture group with the name "1", which is weird.

Normally it would be #{$named} or #{r[:named]}

Ruby =~ vs === Operators

Firstly, =~ is symmetric:

'string' =~ /regex/

And

/regex/ =~ 'string'

Both work.

Secondly as you noted, === works with other classes. If you want to match strings, you should be using the operator for... matching. It is called case operator for a reason - case uses it internally.

case foo
when bar then x
when baz then y
else z
end

Is the same as:

if bar === foo
x
elsif baz === foo
y
else
z
end

Explicitly using === is considered unidiomatic.

Named capturing group to different names

You can nest the named capturing groups and use

^(?<someName>[^ ]*) (?<someNewFancyNae>(?<someNameWeWishToDeprecate>[^ ]*))$

Or,

^(?<someName>\S+)\s+(?<someNewFancyNae>(?<someNameWeWishToDeprecate>\S+))$

See the regex demo.

Sample Image



Related Topics



Leave a reply



Submit