Reputation: 1165
I'm writing a simple method to detect and strip tags from text strings. Given this input string:
{{foobar}}
The function has to return
foobar
I thought I could just chain multiple chomp!
methods, like so:
"{{foobar}}".chomp!("{{").chomp!("}}")
but this won't work, because the first chomp!
returns a NilClass
. I can do it with regular chomp
statements, but I'm really looking for a one-line solution.
The String class documentation says that chomp!
returns a Str
if modifications have been made - therefore, the second chomp!
should work. It doesn't, however. I'm at a loss at what's happening here.
For the purposes of this question, you can assume that the input string is always a tag which begins and ends with double curly braces.
Upvotes: 0
Views: 910
Reputation: 8637
Try tr
:
'{{foobar}}'.tr('{{', '').tr('}}', '')
You can also use gsub
or sub
but if the replacement is not needed as pattern, then tr
should be faster.
If there are always curly braces, then you can just slice the string:
'{{foobar}}'[2...-2]
If you plan to make a method which returns the string without curly braces then DO NOT use bang versions. Modifying the input parameter of a method will be suprising!
def strip(string)
string.tr!('{{', '').tr!('}}', '')
end
a = '{{foobar}}'
b = strip(a)
puts b #=> foobar
puts a #=> foobar
Upvotes: 0
Reputation: 26758
Testing this out, it's clear that chomp!
will return nil if the separator it's provided as an argument is not present at the end of the string.
So "{{text}}".chomp!("}}")
returns a string, but "{{text}}".chomp!("{{")
reurns nil.
See here for an answer of how to chomp
at the beginning of a string. But recognize that chomp
only looks at the end of the string. So you can call str.reverse.chomp!("{{").reverse
to remove the opening brackets.
You could also use a regex:
string = "{{text}}"
puts [/^\{\{(.+)\}\}$/, 1]
# => "text"
Upvotes: 0
Reputation: 176372
You can definitely chain multiple chomp
statements (the non-bang version), still having a one-line solution as you wanted:
"{{foobar}}".chomp("{{").chomp("}}")
However, it will not work as expected because both chomp!
and chomp
removes the separator only from the end of the string, not from the beginning.
You can use sub
"{{foobar}}".sub(/{{(.+)}}/, '\1')
# => "foobar"
"alfa {{foobar}} beta".sub(/{{(.+)}}/, '\1')
# => "alfa foobar beta"
# more restrictive
"{{foobar}}".sub(/^{{(.+)}}$/, '\1')
# => "foobar"
Upvotes: 2