Add multiple consecutive whitespaces in a string replace operation - whitespace

g.e. I would like to prepend all occurrences of the string "foo" with three spaces:
value.replace(/(foo)/, " " + "$1")
value.replace(/(foo)/, " $1")
value.replace(/(foo)/, " " + " " + " $1")
all return
foo
instead of
foo

Did you try the follow GREL expression value.replace('foo', ' foo') ?

Related

How to add escape sequence to String variables?

When adding one escape character to string and printing the output does not replace escape character in the output string
indent = '\t'
message = 'Hello there'
message = "#{indent} #{message}"
puts(message)
From the above code output printed is as below
\t Hello there
What is wrong with this code? What is the way to achieve the intended output?
You have to use " instead ' in:
indent = '\t'
Look:
irb(main):001:0> indent = '\t'
=> "\\t"
irb(main):002:0> indent = "\t"
=> "\t"

Ruby escaping a set of special characters in a string

I have a set of special characters for Elasticsearch that I need to escape with Ruby.
They are: + - = && || > < ! ( ) { } [ ] ^ " ~ * ? : \ /
How can I get any string to escape any of these characters?
Thanks
The problem as it is stated has no solution, because “escaping two subsequent characters” makes no sense. What result do you expect to receive “escaping”, say, &&?
I believe, you want to escape all single characters, so that && becomes \&\& and || — \|\|. That is easy.
to_escape = %w_+ - = & | > < ! ( ) { } [ ] ^ " ~ * ? : \ /_ # C"mon, SO parser
re = Regexp.union(to_escape)
print 'str (f) | a || b'.gsub(re) { |m| "\\#{m}" }
#⇒ str \(f\) \| a \|\| b
Another possibility would be to use Regexp#escape, but it will escape more, than you probably need (e. g. spaces.)
This is a variation on #mudasobwa's answer, using the form of String#gsub that uses a hash for replacements:
escapees = %w$ + - = & | > < ! ( ) { } [ ] ^ " ~ * ? : \ / $
#=> ["+", "-", "=", "&", "|", ">", "<", "!", "(", ")", "{", "}",
# "[", "]", "^", "\"", "~", "*", "?", ":", " /"]
h = escapees.each_with_object({}) { |c,h| h[c] = "\\#{c}" }
#=> {"+"=>"\\+", "-"=>"\\-",..., " /"=>"\\ /"}
h.default_proc = ->(h,k) { k }
If the hash h does not have a key k, Hash#default_proc= causes the h[k] to to return k.
s = 'str (f) | a || b'
ss = s.gsub(/./,h)
#=> "str \\(f\\) \\| a \\|\\| b"
puts ss
#=> str \(f\) \| a \|\| b

Extract string matching regex

I wanted to extract the value between "#" and ":" as well as after ":" within the following string:
str =
"this is some text
Text#7789347: 4444
some text
text # 7789348 : 666,555
some text
"
Output:
"7789347", " 4444"
"7789348", " 666,555"
I am using the following regex:
(\s)*[t|T][e|E][x|X][t|T](\s)*#(\s)*(\d)*(\s)*:.*
I can select the required field, but I don't know how to get the values.
In case you have to match only floating digits, you can use the /(?mi)^\s*\btext\b.*?#\s*(\d+(?:,\d+)?)\s*:\s*(\d+(?:,\d+)?)$/ regex:
str="""this is some text
Text#7789347: 4444
some text
text # 7789348 : 666,555
some text
"""
puts str.scan(/(?mi)^\s*\btext\b.*?#\s*(\d+(?:,\d+)?)\s*:\s*(\d+(?:,\d+)?)$/)
Output of the demo:
7789347
4444
7789348
666,555
You can scan it like this:
str.each_line{ |line|
a = line.scan(/#(.*):(.*)$/)
puts a[0].inspect if !a.empty?
}
# ["7789347", " 4444"]
# [" 7789348 ", " 666,555"]
To get the values you can use: #\s*(.*?)\s*:\s*(\d+(?:,\d+)*)
if line =~ /#\s*(.*?)\s*:\s*(\d+(?:,\d+)*)/
match1 = $~[1]
match2 = $~[2]
else
match = ""
end
Below Regex may help you:
#\s*(\d+)\s*:\s*([0-9,]*)
DEMO

Shorter way to remove non-characters than gsub(/\d|\W/, "")

my_string = 'Here's the #: 49848! - but will dashes, commas & stars (*) show?'
puts src.gsub(/\d|\W/, "")
i.e. can I remove the or ("|").
Here's how I got here, can I get shorter?
src = "Here's the #: 49848! - but will dashes, commas & stars (*) show?"
puts "A) - " + src
puts "B) - " + src.gsub(/\d\s?/, "")
puts "C) - " + src.gsub(/\W\s?/, "")
puts "D) - " + src.gsub(/\d|\W\s?/, "")
puts "E) - " + src.gsub(/\d|\W/, "")
puts "F) - " + src
A) - Here's the #: 49848! - but will dashes, commas & stars (*) show?
B) - Here's the #: ! - but will dashes, commas & stars (*) show?
C) - Heresthe49848butwilldashescommasstarsshow
D) - Heresthebutwilldashescommasstarsshow
E) - Heresthebutwilldashescommasstarsshow
F) - Here's the #: 49848! - but will dashes, commas & stars (*) show?
n.d. D) and E) are what I want for output. Just characters.
my_string = "Here's the #: 49848! - but will dashes, commas & stars (*) show?"
p my_string.delete('^a-zA-Z')
#=>"Heresthebutwilldashescommasstarsshow"
I have this one
src.gsub(/[^a-z]/i, "")
also not shorter, but better to read in my opinion.
The i modifier makes the regex case independent, so that a-z matches also A-Z. A small difference is that this regex will also replace _ which is not replaced by yours.
If you want to keep also unicode letters, use this one:
/\PL/
This matches all non letter character.

Ruby strange quoting

sorry for bad English. Why Ruby quoting so strange? Or may be this is a bug?
irb(main):027:0> p eval "\" \+ \\+ \\\+ \\\\+ \\\\\+ \""
produces
=> " + + + \\+ \\+ "
or
irb(main):027:0> puts eval "\" \+ \\+ \\\+ \\\\+ \\\\\+ \""
produces
=> + + + \+ \+
or another example
irb(main):067:0> " \" " =~ Regexp.new(eval("\" \\\" \""))
=> 0
irb(main):068:0> " + " =~ Regexp.new(eval("\" \\\\+ \""))
=> 0
When you write \" \+ \\+ \\\+ \\\\+ \" you get " + \+ \+ \\+ ". After, you use eval to execute this string, that contains another double-quoted string. You get, then, + + + \+.
\\ => \
\x => x (se não for nenhum caso especial, como \n)
ruby escaping is perfectly good,
eval = evaluate/execute the string

Resources