I'd use:
str = "Hello A=[apple] B=[boy] World"
str[/A=\[(.*?)\]/, 1] # => "apple"
str = "Hello A=[] B=[boy] World"
str[/A=\[(.*?)\]/, 1] # => ""
I'm not sure why you're using A*=*
, because it means "zero or more 'A' followed by zero or more '='" and basically fails to do anything useful, and, in fact, actually opens up a hole to return bad results. See the additional information in the edit below.
Here are variations on the same themes. All are documented in the Regexp and String.[]
documentation:
str = "Hello A=[apple] B=[boy] World"
str[/A=\[(.*?)\]/, 1] # => "apple"
/A=\[(.*?)\]/ =~ str
$1 # => "apple"
str =~ /A=\[(.*?)\]/
$1 # => "apple"
/A=\[(?<in_brackets>.*?)\]/ =~ str
in_brackets # => "apple"
str = "Hello A=[] B=[boy] World"
str[/A=\[(.*?)\]/, 1] # => ""
/A=\[(.*?)\]/ =~ str
$1 # => ""
/A=\[(?<in_brackets>.*?)\]/ =~ str
in_brackets # => ""
the = was intended to match possible space characters before or after the equal sign, e.g. str = "Hello A= [] B=[boy] World"
Well, *=*
isn't how you should do it. You need to tell the regex engine what is optional:
/A *= */
would be correct, as would:
/A ?= ?/
Here's some tests to show you what's happening:
str = "Hello [foo] A = [apple] B=[boy] World"
str[/A*=*\[(.*?)\]/, 1] # => "foo"
str[/A *=*\[(.*?)\]/, 1] # => nil
str[/A *= *\[(.*?)\]/, 1] # => "apple"
str[/A ?= ?\[(.*?)\]/, 1] # => "apple"
Notice that your pattern /A*=*/
allows the engine to match [foo]
, not A = [apple]
. This is because you're telling it to match no A
and no =
as an option, which opens the hole to grab [foo]
. As long as your inputs are exactly two options, with no preceding value inside brackets you'll be safe. If you have an input with that your result will be wrong.
str[/A.*=.*\[(.*?)\]/,1]?
Nope:
str = "Hello A=[apple] B=[boy] World"
str[/A.*=.*\[(.*?)\]/,1] # => "boy"
I'd recommend exploring how to use regex via Rubular. Here's a link showing the above example and why it fails.