Regex - Grab characters between two characters but not including them - ruby-on-rails

I'm trying to grab the rsession variable in the string below between '=' and '&' in a string.
I'm able to do it with /rsession(\=.+?\&)/.
But how do I do it so the output doesn't include the '=' and '&'?
The string is:
"app=1334300&rsession=0806343413_1:5bc6a3c80271826a1c0016c1520d3&token=a6caacf7edfbd9383429e30a1adfadf385208985ad&redirectReq=true"

You can use this regex:
/(?<=rsession=)[^&]*/
Explanation:
(?<= # asserts the match at position after
rsession= # the literal string `rsession=`
) # it is called: positive lookbehind
[^&] # not `&` character
* # as many as possible
Hope it helps.

You can capture it in group like this.
Regex: /rsession=([^&]+)/
Explanation:
([^&]+) will capture in group all characters until a & is met. Use \1 or $1 to use captured group.
Regex101 Demo

Related

Regular expression for capturing hashtags in groups

I need a regular expression to capture a #hashtag in multiple groups(group 1-"#" group 2-"hasshtag").
I tried:
"(\\b#)([a-z0-9]{1,})(\\b)"
But this doesn't capture anything.Any suggestions?
You may use this regex:
"(\\B#)([a-zA-Z0-9]+)"
\B asserts position where \b does not match. Using \b before # will fail the match unless there is a word character before #.
RegEx Demo

How do I replace all the apostrophes that come right before or right after a comma?

I have a string aString = "old_tag1,old_tag2,'new_tag1','new_tag2'"
I want to replace the apostrophees that come right before or right after a comma. For example in my case the apostrophees enclosing new_tag1 and new_tag2 should be removed.
This is what I have right now
aString = aString.gsub("'", "")
This is however problematic as it removes any apostrophe inside for example if I had 'my_tag's' instead of 'new_tag1'. How do I get rid of only the apostrophes that come before or after the commas ?
My desired output is
aString = "old_tag1,old_tag2,new_tag1,new_tag2"
My guess is to use regex as well, but in a slightly other way:
aString = "old_tag1,old_tag2,'new_tag1','new_tag2','new_tag3','new_tag4's'"
aString.gsub /(?<=^|,)'(.*?)'(?=,|$)/, '\1\2\3'
#=> "old_tag1,old_tag2,new_tag1,new_tag2,new_tag3,new_tag4's"
The idea is to find a substring with bounding apostrophes and paste it back without it.
regex = /
(?<=^|,) # watch for start of the line or comma before
' # find an apostrophe
(.*?) # get everything between apostrophes in a non-greedy way
' # find a closing apostrophe
(?=,|$) # watch after for the comma or the end of the string
/x
The replacement part just paste back the content of the first, second, and third groups (everything between parenthesis).
Thanks for #Cary for /x modificator for regexes, I didn't know about it! Extremely useful for explanation.
This answers the question, "I want to replace the apostrophes that come right before or right after a comma".
r = /
(?<=,) # match a comma in a positive lookbehind
\' # match an apostrophe
| # or
\' # match an apostrophe
(?=,) # match a comma in a positive lookahead
/x # free-spacing regex definition mode
aString = "old_tag1,x'old_tag2'x,x'old_tag3','new_tag1','new_tag2'"
aString.gsub(r, '')
#=> => "old_tag1,x'old_tag2'x,x'old_tag3,new_tag1,new_tag2'"
If the objective is instead to remove single quotes enclosing a substring when the left quote is at the the beginning of the string or is immediately preceded by a comma and the right quote is at the end of the string or is immediately followed by comma, several approaches are possible. One is to use a single, modified regex, as #Dimitry has done. Another is to split the string on commas, process each string in the resulting array and them join the modified substrings, separated by commas.
r = /
\A # match beginning of string
\' # match single quote
.* # match zero or more characters
\' # match single quote
\z # match end of string
/x # free-spacing regex definition mode
aString.split(',').map { |s| (s =~ r) ? s[1..-2] : s }.join(',')
#=> "old_tag1,x'old_tag2'x,x'old_tag3',new_tag1,new_tag2"
Note:
arr = aString.split(',')
#=> ["old_tag1", "x'old_tag2'x", "x'old_tag3'", "'new_tag1'", "'new_tag2'"]
"old_tag1" =~ r #=> nil
"x'old_tag2'x" =~ r #=> nil
"x'old_tag3'" =~ r #=> nil
"'new_tag1'" =~ r #=> 0
"'new_tag2'" =~ r #=> 0
Non regex replacement
Regular expressions can get really ugly. There is a simple way to do it with just string replacement: search for the pattern ,' and ', and replace with ,
aString.gsub(",'", ",").gsub("',", ",")
=> "old_tag1,old_tag2,new_tag1,new_tag2'"
This leaves the trailing ', but that is easy to remove with .chomp("'"). A leading ' can be removed with a simple regex .gsub(/^'/, "")

How can I construct a regular expression to account for non-consecutive characters?

I'm currently using this regex for my names \A^[a-zA-Z'.,\s-]*\z; however, I don't want there to be any consecutive characters for a apostrophe, period, comma, whitespace, or hyphen. How can I do this?
The significant part would be (?:[a-zA-Z]|['.,\s-](?!['.,\s-])).
Meaning:
(?:
[a-zA-Z] # letters
| # or
['.,\s-] # any of these
(?!['.,\s-]) # but in front can not be another of these
)
But, in this case:
Guedes, Washington
------^^----------
Would invalidate the name, so maybe you want remove \s from the negative look-ahead.
Hope it helps.
How about this (string of letters, potentially ending with one of those terminator chars)
\A^[a-zA-Z]*['.,\s-]?\z

Regex get from character to whitespace

I'm trying to pull the username from a post in rails. I thought the best way to do this would be using regex and pull from the # to the next whitespace character which would give me the username.
e.g in the string:
'#stackoverflow is good for help'
I would be able to pull from the # to the next whitespace character giving me the string 'stackoverflow'
My regex skills are a little lacking so any help would be appreciated.
Thanks.
You can use \S to match any non-whitespace character, for example:
(?<=#)\S*
Will match any sequence of zero or more non-whitespace characters which appear immediately after a # character. The (?<=…) creates a lookbehind assertion, so the # will not be included in the match.
Demonstration
Alternatively, you could use:
#(\S*)
This will match a #, followed by zero or more non-whitespace characters, captured in group 1.
Demonstration
How about this:
regex = /#(\S*)/
\S here matches all non-whitespace character.

Premature end of char-class

I had the regular expression for email validating following rules
The local-part of the e-mail address may use any of these ASCII characters:
Uppercase and lowercase English letters (a-z, A-Z)
Digits 0 to 9
Characters ! # $ % & ' * + - / = ? ^ _ ` { | } ~
Character . (dot, period, full stop) provided that it is not the first or last character, and provided also that it does not appear two or more times consecutively.
/^(([^<>()[\]\\.,;:\s#\"]+(\.[^<>()[\]\\.,;:\s#\"]+)*)|(\".+\"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/i
It is working in Javascript but in Ruby http://rubular.com/ it gives error "Premature end of char-class".
How can i resolve this?
Brackets are part of regex syntax. If you want to match a literal bracket (or any other special symbol, for that matter), escape with a backslash.
this should work :
/^(([^<>()\[\]\\.,;:\s#\"]+(\.[^<>()\[\]\\.,;:\s#\"]+)*)|(\".+\"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/i
You should escape opening square brackets as well as closings inside the symbol range:
# ⇓ ⇓
/^(([^<>()[\]\\.,;:\s#\"]+(\.[^<>()[\]\\.,;:\s#\"]+)*)…/
This should be:
/^(([^<>()\[\]\\.,;:\s#\"]+(\.[^<>()\[\]\\.,;:\s#\"]+)*)…/
Hope it helps.
irb(main):016:0> /[[e]/
SyntaxError: (irb):16: premature end of char-class: /[[e]/
from /ms/dist/ruby/PROJ/core/2.0.0-p195/bin/irb:12:in `<main>'
In JavaScript regular expression engine, you don't need to escape [ inside a character group []. However, you have to use \[ in Ruby regular expression.
/^(([^<>()\[\]\\.,;:\s#\"]+(\.[^<>()\[\]\\.,;:\s#\"]+)*)|(\".+\"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/i

Resources