Ruby regex to replace character sequence
gsub
with a positive look-ahead will do it.
x = %q[{"1"=>"test","2"=>"Another=>Test","3"=>"Another=>One"}]
x.gsub!(%r{=>(?=\w)}, '|')
puts x
A look-ahead (or look-behind) matches, but does not include that bit in the match.
Though I think %r{=>(?=[^"])}
, a =>
which is not in front of a quote, is more correct.
x = %q[{"1"=>"what about => a space?","2"=>"Or=>(this)"}]
x.gsub!(%r{=>(?=[^"])}, '|')
puts x
Using regex to replace parameters in a string
Neither of your attempt will work because arguments of gsub!
are evaluated prior to the call of gsub!
. parameters[...]
will be evaluated prior to replacement, so it has no way to reflect the match. In addition, "\1"
will not be replaced by the first capture even if that string was the direct argument of gsub!
. You need to escape the escape character like "\\1
". To make it work, you need to give a block to gsub!
.
But instead of doing that, try to use what already is there. You should use string format %{}
and use symbols for the hash.
request.user = "%{user} %{name}"
request.password = "%{password}"
parameters = {user: "first", name: "last", password: "secret"}
request.each do |value|
value.replace(value % parameters)
end
How can I replace every instance of a pattern in ruby?
String.gsub should do the trick.
Quoting docs:
gsub(pattern, replacement) → new_str
Returns a copy of str with the all occurrences of pattern
substituted for the second argument. The pattern is typically a
Regexp; if given as a String, any regular expression metacharacters it
contains will be interpreted literally, e.g.\\d
will match a
backlash followed byd
, instead of a digit.
Ruby Regex Group Replacement
You can use the following regex with back-reference \\1
in the replacement:
reg = /(\\e\[(?:[0-9]{1,2}|[3,9][0-8])m)+Text/
mystring = "\\e[1mHello there\\e[34m\\e[40mText\\e[0m\\e[0m\\e[22m"
puts mystring.gsub(reg, '\\1New Text')
mystring = "\\e[1mHello there\\e[44m\\e[34m\\e[40mText\\e[0m\\e[0m\\e[22m"
puts mystring.gsub(reg, '\\1New Text')
Output of the IDEONE demo:
\e[1mHello there\e[40mNew Text\e[0m\e[0m\e[22m
\e[1mHello there\e[40mNew Text\e[0m\e[0m\e[22m
Mind that your input has backslash \
that needs escaping in a regular string literal. To match it inside the regex, we use double slash, as we are looking for a literal backslash.
How to find & replace a pattern with string in ruby?
First let's write the text to a file:
str =<<BITTER_END
command[check_users]=/usr/local/nagios/libexec/check_users -w 30 -c 35
command[check_load]=/usr/local/nagios/libexec/check_load -w 15,10,5 -c 30,25,20
command[check_disk]=/usr/local/nagios/libexec/check_disk -w 20% -c 10% -p /dev/sda1
command[check_hda]=/usr/local/nagios/libexec/check_disk -w 20% -c 10% -p /dev/sdb
command[check_procs]=/usr/local/nagios/libexec/check_procs -w 200 -c 250
BITTER_END
Fname_in = "in"
Fname_out = "out"
File.write(Fname_in, str)
#=> 390
Now read that file into a string, modify the string and write it to the output file:
File.write(Fname_out, File.read(Fname_in).gsub("/dev/sdb", "/dev/xvda1"))
#=> 392
Let's confirm it worked:
puts File.read(Fname_out)
command[check_users]=/usr/local/nagios/libexec/check_users -w 30 -c 35
command[check_load]=/usr/local/nagios/libexec/check_load -w 15,10,5 -c 30,25,20
command[check_disk]=/usr/local/nagios/libexec/check_disk -w 20% -c 10% -p /dev/sda1
command[check_hda]=/usr/local/nagios/libexec/check_disk -w 20% -c 10% -p /dev/xvda1
command[check_procs]=/usr/local/nagios/libexec/check_procs -w 200 -c 250
How to replace words inside template placeholders
In your Regex, you have added the \A
and \z
anchors. These ensure that your regex only matches, if the string only contains exactly <%= Name %>
with nothing before or after.
To match the your pattern anywhere in the string, you can simply remove the anchors:
parsed_body = body.gsub(/<%= Name %>/, "Some person")
Substitute all matches with values in Ruby regular expression
Actaully you can use gsub, you just have to be careful to use it correctly:
s = 'x[0] = x[1] & x[1] = x[2]'
s.gsub!(/(\w+)\[(\d+)\]/, '\1__\2')
puts s
Result:
x__0 = x__1 & x__1 = x__2
Ruby find a whole math expression in a string using RegEx
Regex Calculators
First off, you might want to have a look at this question about Regex Calculators (both RPN and non-RPN version).
But we're not dealing with parentheses, so we can go with something like:
^\s*-?\d+(?:\s*[-+*/]\s*\d+)+$
See demo.
Explanation
- The
^
anchor asserts that we are at the beginning of the string \s*
allows optional spaces-?
allows an optional minus before the first digit\d+
matches the first digits- The non-capturing group
(?:\s*[-+*/]\s*\d+)
matches optional spaces, an operator, optional spaces and digits - the
+
quantifier matches that one or more times - The
$
anchor asserts that we are at the end of the string
How to change case of letters in string using RegEx in Ruby
@sawa Has the simple answer, and you've edited your question with another mechanism. However, to answer two of your questions:
Is there a way to do this within the regex though?
No, Ruby's regex does not support a case-changing feature as some other regex flavors do. You can "prove" this to yourself by reviewing the official Ruby regex docs for 1.9 and 2.0 and searching for the word "case":
- https://github.com/ruby/ruby/blob/ruby_1_9_3/doc/re.rdoc
- https://github.com/ruby/ruby/blob/ruby_2_0_0/doc/re.rdoc
I don't really understand the '\1' '\2' thing. Is that backreferencing? How does that work?
Your use of \1
is a kind of backreference. A backreference can be when you use \1
and such in the search pattern. For example, the regular expression /f(.)\1/
will find the letter f
, followed by any character, followed by that same character (e.g. "foo" or "f!!").
In this case, within a replacement string passed to a method like String#gsub
, the backreference does refer to the previous capture. From the docs:
"If replacement is a String it will be substituted for the matched text. It may contain back-references to the pattern’s capture groups of the form
\d
, whered
is a group number, or\k<n>
, wheren
is a group name. If it is a double-quoted string, both back-references must be preceded by an additional backslash."
In practice, this means:
"hello world".gsub( /([aeiou])/, '_\1_' ) #=> "h_e_ll_o_ w_o_rld"
"hello world".gsub( /([aeiou])/, "_\1_" ) #=> "h_\u0001_ll_\u0001_ w_\u0001_rld"
"hello world".gsub( /([aeiou])/, "_\\1_" ) #=> "h_e_ll_o_ w_o_rld"
Now, you have to understand when code runs. In your original code…
string.gsub!(/([a-z])([A-Z]+ )/, '\1'.upcase)
…what you are doing is calling upcase
on the string '\1'
(which has no effect) and then calling the gsub!
method, passing in a regex and a string as parameters.
Finally, another way to achieve this same goal is with the block form like so:
# Take your pick of which you prefer:
string.gsub!(/([a-z])([A-Z]+ )/){ $1.upcase << $2.downcase }
string.gsub!(/([a-z])([A-Z]+ )/){ [$1.upcase,$2.downcase].join }
string.gsub!(/([a-z])([A-Z]+ )/){ "#{$1.upcase}#{$2.downcase}" }
In the block form of gsub the captured patterns are set to the global variables $1
, $2
, etc. and you can use those to construct the replacement string.
Related Topics
Rewrite Template.Js.Erb into Template.Js.Slim
Sorting Numeric Strings in Ruby
Error When Starting Sinatra: "Tried to Create Proc Object Without a Block"
How to Combine Multiple Arrays of the Same Size in Ruby
Ruby's "Foo = True If !Defined? Foo" Won't Work as Expected
Openssl::Ssl::Sslcontext Sni Servername_Cb Not Working
Recursively Convert Hash Containing Non-Utf Chars to Utf
Regex "Punct" Character Class Matches Different Characters Depending on Ruby Version
Working with Multiple Processes in Ruby
How to Use Multiple Models for Tag_Cloud
Gem::Ext::Builderror: Error: Failed to Build Gem Native Extension. on Cenos 6.5
Ruby Soap4R Wsdl2Ruby.Rb Errors
Carrierwave and Correct File Extension Depending on Its Contents
Why Aren't "Gem" and "Bundle" Using the Same Libxml2
How to Get the Real File from S3 Using Carrierwave
Ruby Parenthesis Syntax Exception with I++ ++I