I have a string: results = "123 456 "
I would like to iterate through the string and print: "1,2,3, ,4,5,6, "
This is my code thus far:
results.each do |k|
print k, ","
end
I have also tried using each_char.
This should work:
results.split('').join(',')
# => "1,2,3, ,4,5,6, "
results.each_char.map
# => ["1", "2", "3", " ", "4", "5", "6", " "]
Or, if you want a string as output:
result.each_char.map.join(',')
# => "1,2,3, ,4,5,6, "
each_char works for me:
results = "123 456 "
results.each_char do |char|
print "#{char},"
end
Output:
1,2,3, ,4,5,6, ,
"123 456 ".gsub(/(?<!\A)(?!\z)/, ",")
# => "1,2,3, ,4,5,6, "
Related
I need to remove white spaces after some characters, not all of them. I want to remove whites spaces after these chars: I,R,P,O. How can I do it?
"I ".gsub(/(?<=[IRPO]) /, "") # => "I"
"A ".gsub(/(?<=[IRPO]) /, "") # => "A "
" P $ R 3I&".gsub(/([IRPO])\s+/,'\1')
#=> " P$ R3I&"
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
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
I want to remove unwanted symbols from this string:
myString = String.new("##106#107#Hello##106#World##")
and separate each word with a comma. The desired result is:
"Hello, World"
Any ideas on how to achieve my desired result? What I tried is this:
myString.gsub!(/[##0123456789]/, ',')
print myString + "\n"
# => ",,,,,,,,,,Hello,,,,,,World,,"
There are a couple of ways:
myString.scan(/[a-zA-Z]+/).join(', ')
=> "Hello, World"
myString.gsub(/(\A)?[^a-zA-Z]+(\z)?/){$1 || $2 ? "" : ", "}
# => "Hello, World"
I'm trying to split the string:
"[test| blah] \n [foo |bar bar bar]\n[test| abc |123 | 456 789]"
into the following array:
[
["test","blah"]
["foo","bar bar bar"]
["test","abc","123","456 789"]
]
I tried the following, but it isn't quite right:
"[test| blah] \n [foo |bar bar bar]\n[test| abc |123 | 456 789]"
.scan(/\[(.*?)\s*\|\s*(.*?)\]/)
# =>
# [
# ["test", "blah"]
# ["foo", "bar bar bar"]
# ["test", "abc |123 | 456 789"]
# ]
I need to split at every pipe instead of the first pipe. What would be the correct regular expression to achieve this?
s = "[test| blah] \n [foo |bar bar bar]\n[test| abc |123 | 456 789]"
arr = s.scan(/\[(.*?)\]/).map {|m| m[0].split(/ *\| */)}
Two alternatives:
s = "[test| blah] \n [foo |bar bar bar]\n[test| abc |123 | 456 789]"
s.split(/\s*\n\s*/).map{ |p| p.scan(/[^|\[\]]+/).map(&:strip) }
#=> [["test", "blah"], ["foo", "bar bar bar"], ["test", "abc", "123", "456 789"]]
irb> s.split(/\s*\n\s*/).map do |line|
line.sub(/^\s*\[\s*/,'').sub(/\s*\]\s*$/,'').split(/\s*\|\s*/)
end
#=> [["test", "blah"], ["foo", "bar bar bar"], ["test", "abc", "123", "456 789"]]
Both of them start by splitting on newlines (throwing away surrounding whitespace).
The first one then splits each chunk by looking for anything that is not a [, |, or ] and then throws away extra whitespace (calling strip on each).
The second one then throws away leading [ and trailing ] (with whitespace) and then splits on | (with whitespace).
You cannot get the final result you want with a single scan. About the closest you can get is this:
s.scan /\[(?:([^|\]]+)\|)*([^|\]]+)\]/
#=> [["test", " blah"], ["foo ", "bar bar bar"], ["123 ", " 456 789"]]
…which drops information, or this:
s.scan /\[((?:[^|\]]+\|)*[^|\]]+)\]/
#=> [["test| blah"], ["foo |bar bar bar"], ["test| abc |123 | 456 789"]]
…which captures the contents of each "array" as a single capture, or this:
s.scan /\[(?:([^|\]]+)\|)?(?:([^|\]]+)\|)?(?:([^|\]]+)\|)?([^|\]]+)\]/
#=> [["test", nil, nil, " blah"], ["foo ", nil, nil, "bar bar bar"], ["test", " abc ", "123 ", " 456 789"]]
…which is hardcoded to a maximum of four items, and inserts nil entries that you would need to .compact away.
There is no way to use Ruby's scan to take a regex like /(?:(aaa)b)+/ and get multiple captures for each time the repetition is matched.
Why the hard path (single regex)? Why not a simple combo of splits? Here are the steps, to visualize the process.
str = "[test| blah] \n [foo |bar bar bar]\n[test| abc |123 | 456 789]"
arr = str.split("\n").map(&:strip) # => ["[test| blah]", "[foo |bar bar bar]", "[test| abc |123 | 456 789]"]
arr = arr.map{|s| s[1..-2] } # => ["test| blah", "foo |bar bar bar", "test| abc |123 | 456 789"]
arr = arr.map{|s| s.split('|').map(&:strip)} # => [["test", "blah"], ["foo", "bar bar bar"], ["test", "abc", "123", "456 789"]]
This is likely far less efficient than scan, but at least it's simple :)
A "Scan, Split, Strip, and Delete" Train-Wreck
The whole premise seems flawed, since it assumes that you will always find alternation in your sub-arrays and that expressions won't contain character classes. Still, if that's the problem you really want to solve for, then this should do it.
First, str.scan( /\[.*?\]/ ) will net you three array elements, each containing pseudo-arrays. Then you map the sub-arrays, splitting on the alternation character. Each element of the sub-array is then stripped of whitespace, and the square brackets deleted. For example:
str = "[test| blah] \n [foo |bar bar bar]\n[test| abc |123 | 456 789]"
str.scan( /\[.*?\]/ ).map { |arr| arr.split('|').map { |m| m.strip.delete '[]' }}
#=> [["test", "blah"], ["foo", "bar bar bar"], ["test", "abc", "123", "456 789"]]
Verbosely, Step-by-Step
Mapping nested arrays is not always intuitive, so I've unwound the train-wreck above into more procedural code for comparison. The results are identical, but the following may be easier to reason about.
string = "[test| blah] \n [foo |bar bar bar]\n[test| abc |123 | 456 789]"
array_of_strings = string.scan( /\[.*?\]/ )
#=> ["[test| blah]", "[foo |bar bar bar]", "[test| abc |123 | 456 789]"]
sub_arrays = array_of_strings.map { |sub_array| sub_array.split('|') }
#=> [["[test", " blah]"],
# ["[foo ", "bar bar bar]"],
# ["[test", " abc ", "123 ", " 456 789]"]]
stripped_sub_arrays = sub_arrays.map { |sub_array| sub_array.map(&:strip) }
#=> [["[test", "blah]"],
# ["[foo", "bar bar bar]"],
# ["[test", "abc", "123", "456 789]"]]
sub_arrays_without_brackets =
stripped_sub_arrays.map { |sub_array| sub_array.map {|elem| elem.delete '[]'} }
#=> [["test", "blah"], ["foo", "bar bar bar"], ["test", "abc", "123", "456 789"]]