Ruby Regexp to Replace Equations

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 by d, 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, where d is a group number, or \k<n>, where n 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



Leave a reply



Submit