How do I split a string without keeping the delimiter? - ruby

In Ruby, how do I split a string and not keep the delimiter in the resulting split array? I though tthis was the default, but when I try
2.4.0 :016 > str = "a b c"
=> "a b c"
2.4.0 :017 > str.split(/([[:space:]]|,)+/)
=> ["a", " ", "b", " ", "c"]
I see the spaces included in my result. I would like the result to simply be
["a", "b", "c"]

From the String#split documentation:
If pattern contains groups, the respective matches will be returned in the array as well.
Answering your explicitly stated question: do not match the group:
# ⇓⇓ HERE
str.split(/(?:[[:space:]]|,)+/)
or, even without groups:
str.split(/[[:space:],]+/)
or, in more Rubyish way:
'a b, c,d e'.split(/[\p{Space},]+/)
#⇒ ["a", "b", "c", "d", "e"]

String#splitsplits on white-space by default, so don 't bother with a regex:
"a b c".split # => ["a", "b", "c"]

Try this please
str.split(' ')

Related

In Ruby, how do I split on two or more spaces or a tab?

With Ruby, how do I split into two or more spaces or a tab? that is I have:
2.4.0 :005 > str = "a\t\tb c d"
=> "a\t\tb c d"
and applying my rules above, I would like the result to be:
["a", "", "b", "c d"]
since the consecutive tabs are capturing an empty string. But when I try the below:
2.4.0 :007 > str.split(/(?:[[:space:]][[:space:]]+|\t)/)
=> ["a", "b", "c d"]
The tabs are getting merged into a single [[:space:]].
How do I adjust my regular expression to split into two or more spaces or a tab character?
You could try this:
"a\t\tb c d".split(/\t| {2,}/)
#=> ["a", "", "b", "c d"]
"ab \t\t\tf".split(/\t| {2,}/)
#=> ["ab ", "", "", "f"]
Where \t is for a tab and {2,} for two or more spaces. Notice that there is a space before {2,}.
To include non-breaking spaces you could add \u00A0 to the expression, like this:
str.split(/\t|[ |\u00A0]{2,}/)
Examples:
str = "a\t\tb \u00A0 c d" #=> "a\t\tb   c d"
str.split(/\t|[ |\u00A0]{2,}/) #=> ["a", "", "b", "c d"]
str = "ab \t\t\tf" #=> "ab \t\t\tf"
str.split(/\t|[ |\u00A0]{2,}/) #=> ["ab ", "", "", "f"]
Where [ |\u00A0]{2,} will check for 2 or more occurrences of either a space or non-breaking space.

How do I split on multiple conditions?

With Ruby how do I split on either one of tow conditions -- wheter there are 3 or more spaces or a tab charadter? I tried this
2.4.0 :003 > line = "a\tb\tc"
=> "a\tb\tc"
2.4.0 :004 > line.split(/([[:space:]][[:space:]][[:space:]]+|\t)/)
=> ["a", "\t", "b", "\t", "c"]
but as you can see, the tab character itself is getting included in my results. The results should be
["a", "b", "c"]
What about just split?
p "a\tb\tc".split
# ["a", "b", "c"]
p "a\tb\tc\t\tc\t\t\t\t\t\t\tc\ts\ts\tt".split
# ["a", "b", "c", "c", "c", "s", "s", "t"]
Although that doesn't split when there are three 3 or more white spaces, this might work:
p "a\tb\tc\t\tc\t\t\ t\t\tc\ts\ts\tt".split(/\s{3,}|\t/)
# => ["a", "b", "c", "c", "t", "c", "s", "s", "t"]
line = "aa bb cc\tdd"
line.split /\p{Space}{3,}|\t+/
#⇒ ["aa bb", "cc", "dd"]

Splitting a string into an array ruby

I am trying to turn this string
"a,bc,c"
into this array..
["a", "b", "c"]
I've used split on the comma & iterated through it but I'd like to find a cleaner way.
Thanks!
I will use #scan and #uniq method.
"a, bc,c".scan(/[a-z]/).uniq
# => ["a", "b", "c"]
Here we go, one option:
"a, bc,c".gsub(/\W+/, '').chars.uniq
# Outputs:
=> ["a", "b", "c"]

Format data in string to array?

I need to convert data from a string to an array. The string looks like this:
{a,b,c{1,2,3},d,e,f{11,22,33},g}
The array that I want to receive should look like this:
[a, b, c1, c2, c3, d, e, f11, f22, f33, g]
I tried to use the split method but it works poorly.
arr = str.split(' ');
keys = arr[0][2..-2]
keys = keys.split(',')
Do you have any ideas how it could be implemented?
Here's what I'd use:
string = '{a,b,c{1,2,3},d,e,f{11,22,33},g}'
array = string.scan(/[a-z](?:{.+?})?/).flat_map{ |s|
if s['{']
prefix = s[0]
values = s.scan(/\d+/)
([prefix] * values.size).zip(values).map(&:join)
else
s
end
}
array # => ["a", "b", "c1", "c2", "c3", "d", "e", "f11", "f22", "f33", "g"]
Here's how it works:
string.scan(/[a-z](?:{.+?})?/) # => ["a", "b", "c{1,2,3}", "d", "e", "f{11,22,33}", "g"]
returns the string broken into chunks, looking for a single letter followed by an optional string of { with some text then }.
values = s.scan(/\d+/) # => ["1", "2", "3"], ["11", "22", "33"]
As it's running in flat_map, if { is found, the numbers are scanned out.
([prefix] * values.size).zip(values).map(&:join) # => ["c1", "c2", "c3"], ["f11", "f22", "f33"]
And then an array of the prefix, with the same number of elements as there are values is created and zipped together, resulting in:
[["c", "1"], ["c", "2"], ["c", "3"]], [["f", "11"], ["f", "22"], ["f", "33"]]
The join glues those sub-arrays together. And flat_map flattens any subarrays created so the resulting output is a single array.
You need to arr = str.split(',') in the first step, because there is no whitespace between the values.
Also keep in mind you have {} to handle too.
This worked for me with simple regex and gsubing (though Tin Man's solution is better ruby):
def my_string_to_array(input_string)
groups = input_string.scan(/\w+\{.*?\}/)
groups.each do |group|
modified = group.gsub(',', ",#{group.match(/\w+/)[0]}").delete("{}")
input_string.gsub!(group, modified)
end
created_array = input_string.delete("{}").split(',')
end
string = '{a,b,c{1,2,3},d,e,f{11,22,33},g}'
my_string_to_array(string)
=> ["a", "b", "c1", "c2", "c3", "d", "e", "f11", "f22", "f33", "g"]
The way it works is that it first finds the groups having alphabets followed by braces and digits (like c{1,2,3})
For each such group, it modifies it by gsubing ',' with ',<alphabet>' and removing the braces.
Next, it replaces these groups with the modified ones in the original string.
And finally it removes the starting and ending braces in the original string, and converts it into an array.

Separating vowels and consonants

How can you separate vowels and consonants from strings, to create a filter?
How can i replace the consonants and vowels with other letters
I came up with this
(\A[^aeio]{1,3})(\w*)/
while searching online, but not sure exactly how it works past the filtering part of ^aeio, to get consonants.
String.tr is good for transforming text:
str = "while searching online, but not sure exactly how it works past the filtering part of ^aeio, to get consonants."
p str.tr('aeiou', '')
#=> "whl srchng nln, bt nt sr xctly hw t wrks pst th fltrng prt f ^, t gt cnsnnts."
p str.tr('^aeiou', '') # the ^ negates
#=>"ieeaioieuoueeaoioaeieiaoaeiooeooa"
p str.tr('aeiou', 'eioua')
#=>"wholi sierchong unloni, bat nut sari ixectly huw ot wurks pest thi foltirong pert uf ^eiou, tu git cunsunents."
Do you mean split like this?
1.9.3-p327 > s = "abcqwertyaeiouvbnmi"
=> "abcqwertyaeiouvbnmi"
1.9.3-p327 > s.split(/([aeiou]+)/)
=> ["", "a", "bcqw", "e", "rty", "aeiou", "vbnm", "i"]
If so, then you could just loop through the resulting array replacing characters as you go.
s = "iamagoodboy"
v,c = s.chars.partition{|i| ["a","e","i","o","u"].include?(i)}
p v #=> ["i", "a", "a", "o", "o", "o"]
p c #=> ["m", "g", "d", "b", "y"]
Now you can iterate on v and c as you want.

Resources