Regex to match string excluding first character - ruby

I'm writing ruby and need some help with regex. And I'm really noob in regexp.
I have a string like this
/hello/world
I would like to #gsub this string to change the second slash to %2F.
The challange for me to ignore the first slash and to change only the second slash.
I tried this one
[^/]/
but it chooses not clean slash but o/ in
/hello/world
Please, help me. Thanks!!

You can simply capture the character before the slash in a group and use that in the replacement, for example:
"/hello/world".gsub(/([^\/])\//, '\1%2F') #=> "/hello%2Fworld"
Or if you just want to match any / that appears after the first character, you can simplify this to:
"/hello/world".gsub(/(.)\//, '\1%2F') #=> "/hello%2Fworld"
Or like this:
"/hello/world".gsub(/(?<!^)\//, '%2F') #=> "/hello%2Fworld"

And now for an uglier, regexless alternative:
"/hello/world".split("/").tap(&:shift).unshift("/").join("")
I'll see myself out.

You need to use subpattern within () for find substring:
/^\/(.*)$/
or
/^.(.*)$/
this pattern excluding first character. And then replace / in this substring

(?!^\/)\/
http://rubular.com/r/IRWptAJdLs is a a working example.

change the second / to %2F:
'/hello/world'.sub /(\/.*?)\//, '\1%2F'
#=> "/hello%2Fworld"

Related

Ruby capture words between two colons

I want to capture any word between two colons. I tried with this (try on Rubular):
(\:.*\:)
Hello :name:
What are you doing today, :title:?
$:name:, have a lovely :event:.
It works except the last line it captures this:
Match 3
1. :name:, have a lovely :event:
It's getting tripped up by the second (closing) colon and the third (opening) colon. It should capture :name: and :event: individually on that last line.
You need a non-greedy regular expression:
(\:.*?\:)
The .*? will match the shortest possible string, whereas .* matches the longest string found.
For any word between two colons:
(?<=:)\b.*?\b(?=:)
Rubular link
(\:[^:]*\:)
[^:] means "anything but a ':'.
Please be aware that this expression will match "::" also.
Here is your rubular link updated: http://rubular.com/r/VtwhIqtbli.

Split and Modify Last

I have a string “shared/errors”, and I’d like for the the word “error” to be prepended with an underscore, so as to achieve “shared/_errors” Is there some ruby magic for doing this?
Assuming there is only a single slash in the string, all that is necessary is
string.sub!(%r|(?<=/)|, '_')
or, if you prefer,
string.sub!('/', '/_')
If there are multiple slashes in the string and you only want to affect the last one, then you want
string.sub!(%r|(?=[^/]*\z)|, '_')
If you only want to do this on the last occurrence of the forward slash you can insert an underscore at the index of the slash:
string.insert(string.rindex('/') + 1, '_')
Perhaps all answers are valid here, but I did see that OP references 'errors' by name. Rather than the slash.
string.gsub!('error', '_error') should change the original string, and do so, for all occurrences that may happen in the string. Of course, I have a feeling the slash is important, so perhaps the more correct string.gsub!('/error', '/_error') will do better.
Why not
path = 'shared/errors' # or whatever it is
dir, file = path.match(/^(.*\/)([^/]*)$/).captures
path = dir + "_" + file
This will get the two parts of the string:
shared/errors ==> shared/ + errors
And then patch them back together to form the desired string.

Why is my regular expression skipping the dot instead of matching the string before it?

I was trying to work out a regular expression in IRB and got some unexpected output.
The goal was to match everything up until the last dot in a FQDN.
So, for example, if I was trying to match the string "flowtechconsulting.com",
I started with the following:
s1.sub(/^(.*)\\./, "\\1") #=> "flowtechconsultingcom"
However, the sub function simply returned everything but the dot, instead of the first matching group.
If I add two matching groups it works:
s1.sub(/^(.*)\\.(.*)$/, "\\1") #=> "flowtechconsulting"
I'm just not sure why the first doesn't work. It seems like it should.
/^(.*)\./ only captures everything up to the dot. The "com" is not captured and thus not replaced in the substitution.
Forget about sub, and do something like:
"foo.bar.baz.com"[/(.*)(?:\.)/, 1]
# => "foo.bar.baz"

Ruby regex to remove / from string

I currently have a string to remove spaces from strings, however I now need to remove forward slashes from the string too. I'm not very good with regexes and could use some help thanks. This is the current regex I have: gsub(/\s+/, "") how do I modify this to remove / ? I've played around in the console and can't seem to get it.
You have to escape the forward slash because it's a special character. Something like this:
s = "This is a line / string"
s.gsub(/[\s\/]/, '') # => "Thisisalinestring"

Ruby RegEx problem text.gsub[^\W-], '') fails

I'm trying to learn RegEx in Ruby, based on what I'm reading in "The Rails Way". But, even this simple example has me stumped. I can't tell if it is a typo or not:
text.gsub(/\s/, "-").gsub([^\W-], '').downcase
It seems to me that this would replace all spaces with -, then anywhere a string starts with a non letter or number followed by a dash, replace that with ''. But, using irb, it fails first on ^:
syntax error, unexpected '^', expecting ']'
If I take out the ^, it fails again on the W.
>> text = "I love spaces"
=> "I love spaces"
>> text.gsub(/\s/, "-").gsub(/[^\W-]/, '').downcase
=> "--"
Missing //
Although this makes a little more sense :-)
>> text.gsub(/\s/, "-").gsub(/([^\W-])/, '\1').downcase
=> "i-love-spaces"
And this is probably what is meant
>> text.gsub(/\s/, "-").gsub(/[^\w-]/, '').downcase
=> "i-love-spaces"
\W means "not a word"
\w means "a word"
The // generate a regexp object
/[^\W-]/.class
=> Regexp
Step 1: Add this to your bookmarks. Whenever I need to look up regexes, it's my first stop
Step 2: Let's walk through your code
text.gsub(/\s/, "-")
You're calling the gsub function, and giving it 2 parameters.
The first parameter is /\s/, which is ruby for "create a new regexp containing \s (the // are like special "" for regexes).
The second parameter is the string "-".
This will therefore replace all whitespace characters with hyphens. So far, so good.
.gsub([^\W-], '').downcase
Next you call gsub again, passing it 2 parameters.
The first parameter is [^\W-]. Because we didn't quote it in forward-slashes, ruby will literally try run that code. [] creates an array, then it tries to put ^\W- into the array, which is not valid code, so it breaks.
Changing it to /[^\W-]/ gives us a valid regex.
Looking at the regex, the [] says 'match any character in this group. The group contains \W (which means non-word character) and -, so the regex should match any non-word character, or any hyphen.
As the second thing you pass to gsub is an empty string, it should end up replacing all the non-word characters and hyphens with empty string (thereby stripping them out )
.downcase
Which just converts the string to lower case.
Hope this helps :-)
You forgot the slashes. It should be /[^\W-]/
Well, .gsub(/[^\W-]/,'') says replace anything that's a not word nor a - for nothing.
You probably want
>> text.gsub(/\s/, "-").gsub(/[^\w-]/, '').downcase
=> "i-love-spaces"
Lower case \w (\W is just the opposite)
The slashes are to say that the thing between them is a regular expression, much like quotes say the thing between them is a string.

Resources