Wrap parentheses - ruby

I'm trying to wrap parentheses around string in ruby, only if it isn't wrapped yet:
"my string (to_wrap)" => "my string (to_wrap)"
"my string to_wrap" => "my string (to_wrap)"
I've tried something like:
to_wrap = 'to_wrap'
regexp = Regexp.new "(?!\()#{to_wrap}(?!\))"
string.sub(regexp, "(#{to_wrap})")
but it does not work.
Thanks in advance!

You are very close. Your first negative lookaround is a lookahead, though. So it looks at the first character of to_wrap. Just make that a lookbehind:
"(?<!\()#{to_wrap}(?!\))"
And just to present you with an alternative option to escape parentheses (it's really a matter of taste which on to use, but I find it more easily readable):
"(?<![(])#{to_wrap}(?![)])"

Related

Serialize hash as string similar to json with single quotes in Ruby

Is there a way to convert a hash, possibly nested:
{:event=>"subscribe", :channel=>"data_channel", :parameters=>{:api_key=>"XXX", :sign=>"YYY"}}
into a string in specified format as below?
"{'event':'subscribe', 'channel':'data_channel', 'parameters': {'api_key':'XXX', 'sign':'YYY'}}"
EDIT
The format reminds JSON, but practically is not due to single quotes.
Make JSON, then fix it up:
require 'json'
hash = {:event=>"subscribe", :channel=>"data_channel",
:parameters=>{:api_key=>"XXX", :sign=>%q{Miles "Chief" O'Brien}}}
puts hash.to_json.gsub(/"((?:\\[\"]|[^\"])*)"/) { |x|
%Q{'#{$1.gsub(/'|\\"/, ?' => %q{\'}, %q{\\"} => ?")}'}
}
# => {'event':'subscribe','channel':'data_channel',
# 'parameters':{'api_key':'XXX','sign':'Miles "Chief" O\'Brien'}}
EDIT: The first regex says: match a double quote, then a sequence of either escaped double quotes/backslashes, or non-double-quote/backslash characters, then a double quote again. This makes sure we only find strings, and not accidental half-strings like "Miles \". For each such string, we surround the bit that was inside the double quotes ($1) with single quotes, and run a sub-replacement on it that will find escaped double quotes and unescaped single quotes, unescape the former and escape the latter.
Also, sorry about wonky highlighting, seems StackOverflow syntax highlighter can't deal with alternate forms of Ruby quoting, but they're so convenient when you're working with quote characters...
Your desired output looks like a JSON. Try
require 'json'
JSON.dump(hash)
=> "{\"event\":\"subscribe\",\"channel\":\"data_channel\",\"parameters\":{\"api_key\":\"XXX\",\"sign\":\"YYY\"}}"
To have single quotes you can try something like:
JSON.dump(hash).gsub('"', '\'')
It returns:
{'event':'subscribe','channel':'data_channel','parameters':{'api_key':'XXX','sign':'YYY'}}

Ruby Regex Rubular vs reality

I have a string and I want to remove all non-word characters and whitespace from it. So I thought Regular expressions would be what I need for that.
My Regex looks like that (I defined it in the string class as a method):
/[\w&&\S]+/.match(self.downcase)
when I run this expression in Rubular with the test string "hello ..a.sdf asdf..," it highlioghts all the stuff I need ("hellloasdfasdf") but when I do the same in irb I only get "hello".
Has anyone any ideas about why that is?
Because you use match, with returns one matching element. If you use scan instead, all should work properly:
string = "hello ..a.sdf asdf..,"
string.downcase.scan(/[\w&&\S]+/)
# => ["hello", "a", "sdf", "asdf"]
\w means [a-zA-Z0-9_]
\S means any non-whitespace character [a-zA-Z_-0-9!##$%^&*\(\)\\{}?><....etc]
so using a \w and \S condition is ambiguous.
Its like saying What is an intersection of India and Asia. Obviously its going to be India. So I will suggest you to use \w+.
and you can use scan to get all matches as mentioned in the second answer :
string = "hello ..a.sdf asdf..,"
string.scan(/\w+/)

Ruby regex: operator and

I have an string of an email that looks like "<luke#example.com>"
I would like to use regex for deleting "<" and ">", so I wanted something like
"<luke#example.com>".sub /<>/, ""
The problem is quite clear, /<>/ doesn't wrap what I want. I tried with different regex, but I don't know how to choose < AND >, it is there any and operator where I can say: "wrap this and this"?
As written, your regex matches the literal substring "<>" only. You need to use [] to make them a character class so that they're matched individually, and gsub to replace all matches:
"<luke#example.com>".gsub(/[<>]/, "") # => "luke#example.com"
"<luke#example.com>".gsub /[<>]/, ""
http://regex101.com/r/hP3sY2
If you only ever want to strip the < and > from the start and end only, you can use this:
'<luke#example.com>'.sub(/\A<([^<>]+)>\z/, '\1')
You don't need, nor should you use, a regex.
string[1..-2]
is enough.

Ruby string sub without regex back references

I'm trying to do a simple string sub in Ruby.
The second argument to sub() is a long piece of minified JavaScript which has regular expressions contained in it. Back references in the regex in this string seem to be effecting the result of sub, because the replaced string (i.e., the first argument) is appearing in the output string.
Example:
input = "string <!--tooreplace--> is here"
output = input.sub("<!--tooreplace-->", "\&")
I want the output to be:
"string \& is here"
Not:
"string & is here"
or if escaping the regex
"string <!--tooreplace--> is here"
Basically, I want some way of doing a string sub that has no regex consequences at all - just a simple string replace.
To avoid having to figure out how to escape the replacement string, use Regex.escape. It's handy when replacements are complicated, or dealing with it is an unnecessary pain. A little helper on String is nice too.
input.sub("<!--toreplace-->", Regexp.escape('\&'))
You can also use block notation to make it simpler (as opposed to Regexp.escape):
=> puts input.sub("<!--tooreplace-->") {'\&'}
string \& is here
Use single quotes and escape the backslash:
output = input.sub("<!--tooreplace-->", '\\\&') #=> "string \\& is here"
Well, since '\\&' (that is, \ followed by &) is being interpreted as a special regex statement, it stands to reason that you need to escape the backslash. In fact, this works:
>> puts 'abc'.sub 'b', '\\\\&'
a\&c
Note that \\\\& represents the literal string \\&.

How do I strip parenthesis from a string in Ruby?

I have a string, like this:
"yellow-corn-(corn-on-the-cob)"
and I would like to strip the parenthesis from the string to get something like this:
"yellow-corn-corn-on-the-cob"
I believe you would use gsub to accomplish this, but I'm not sure what pattern I would need to match the parenthesis. Something like:
clean_string = old_string.gsub(PATTERN,"")
Without regular expression:
"yellow-corn-(corn-on-the-cob)".delete('()') #=> "yellow-corn-corn-on-the-cob"
Try this:
clean_string = old_string.gsub(/[()]/, "")
On a side note, Rubular is awesome to test your regular expressions quickly.

Resources