Remove extra white space but leave one space remaining in string - ruby

I want to be able to take in a string with the word 'WUB' placed randomly throughout it, and remove those instances replaced with white space.
Ex. "WUBWUBWUBWEWUBWUBAREWUBWUBWUBTHEWUBCHAMPIONSWUBWUBMYWUBFRIENDS"
turns into...
WE ARE THE CHAMPIONS MY FRIENDS
However the problems stands that I receive that with extra white space for each 'WUB.' How can I take out the extra white space and retain only one single white space?
def song_decoder(song)
song.gsub!(/WUB/, " ")
song.strip!
print song
return song
end
song_decoder("WUBWUBWUBWEWUBWUBAREWUBWUBWUBTHEWUBCHAMPIONSWUBWUBMYWUBFRIENDS")
# above is test case

/WUB/ gets all the "WUB" in the string, so if there are some consecutive ones, you'll have two white spaces, and using strip on the result, just would remove all whitespaces, so wouldn't be what you expect.
You could get any "WUB" as groups and replace them with ' '. As this specific result leaves you just with an initial whitespace (first character), lstrip would deal with that:
str = 'WUBWUBWUBWEWUBWUBAREWUBWUBWUBTHEWUBCHAMPIONSWUBWUBMYWUBFRIENDS'
p str.gsub(/(WUB)+/, ' ').lstrip
# "WE ARE THE CHAMPIONS MY FRIENDS"

I just found the squeeze method!
def song_decoder(song)
song.gsub!(/WUB/, " ")
song.strip!
song.squeeze!(" ")
print song
return song
end
This does exactly what I need. My apologies.

Without regular expression:
"WUBWUBWUBWEWUBWUBAREWUBWUBWUBTHEWUBCHAMPIONSWUBWUBMYWUBFRIENDS".
split('WUB').reject(&:empty?).join(' ')
#⇒ "WE ARE THE CHAMPIONS MY FRIENDS"

Related

Check 4 chars with regex Ruby console input

I have 4 chars, first one is letter 'L' for example, the other two are numbers and the last one is letter again, all of them are separated by one space. User is entering them in the Ruby console. I need to check that they are separated by one space and don't have other weird characters and that there is nothing after the last letter.
So if a user enters for example gets.chomp = 'L 5 7 A', I need to check that everything is ok and separated by only one space and return input[1], input[2], input[3]. How can I do that? Thanks.
You can do something like this:
puts "Enter string"
input = gets.chomp
r = /^(L)\s(\d)\s(\d)\s([A-Z])$/
matches = input.match r
puts matches ? "inputs: #{$1}, #{$2}, #{$3}, #{$4}" : "input-format incorrect"
Here $1 is the first capture, similarly for $2, $3 etc. If you want to store the result in an array you can use:
matches = input.match(r).to_a
then the first element is the entire match, followed by each capture.
Try
/^\w\s(\d)\s(\d)\s(\w)$/
Rubular is a good sandbox site for experimenting with and debugging regexes.

Erase word from ruby that contains a certain char

As the tittle suggests, I'd like to get some chars and check if the string as any of them. If I suppose, for example, "!" to be forbidden, then string.replace("",word_with_!). How can I check for forbidden chars if forbidden_chars is an array?
forbidden_chars = ["!",",",...]
check ARRAY (it is the string split into an array) for forbidden chars
erase all words with forbidden chars
Could anyone help me please? I just consider searching for the words with the cards and retrieving index as mandatory in the answer please. Thank you very much :)
string = 'I like my coffee hot, with no sugar!'
forbidden_chars = ['!', ',']
forbidden_chars_pattern = forbidden_chars.map(&Regexp.method(:escape)).join('|')
string.gsub /\S*(#{forbidden_chars_pattern})\S*/, ''
# => "I like my coffee with no "
The idea is to match as many non-white space characters as possible \S*, followed by any of the forbidden characters (!|,), followed by as many non-white space characters as possible again.
The reason we need the Regexp.escape is for the cases when a forbidden character has special regex meaning (like .).
string = 'I like my coffee strong, with no cream or sugar!'
verboten = '!,'
string.split.select { |s| s.count(verboten).zero? }.join ' '
#=> "I like my coffee with no cream or"
Note this does not preserve the spacing between "I" and "like" but if there are no extra spaces in string it returns a string that has no extra spaces.

removing all spaces within a specific string (email address) using ruby

The user is able to input text, but the way I ingest the data it often contains unnecessary carriage returns and spaces.
To remove those to make the input look more like a real sentence, I use the following:
string.delete!("\n")
string = string.squeeze(" ").gsub(/([.?!]) */,'\1 ')
But in the case of the following, I get an unintended space in the email:
string = "Hey what is \n\n\n up joeblow#dude.com \n okay"
I get the following:
"Hey what is up joeblow#dude. com okay"
How can I enable an exception for the email part of the string so I get the following:
"Hey what is up joeblow#dude.com okay"
Edited
your method does the following:
string.squeeze(" ") # replaces each squence of " " by one space
gsub(/([.?!] */, '\1 ') # check if there is a space after every char in the between the brackets [.?!]
# and whether it finds one or more or none at all
# it adds another space, this is why the email address
# is splitted
I guess what you really want by this is, if there is no space after punctuation marks, add one space. You can do this instead.
string.gsub(/([.?!])\W/, '\1 ') # if there is a non word char after
# those punctuation chars, just add a space
Then you just need to replace every sequence of space chars with one space. so the last solution will be:
string.gsub(/([.?!])(?=\W)/, '\1 ').gsub(/\s+/, ' ')
# ([.?!]) => this will match the ., ?, or !. and capture it
# (?=\W) => this will match any non word char but will not capture it.
# so /([.?!])(?=\W)/ will find punctuation between parenthesis that
# are followed by a non word char (a space or new line, or even
# puctuation for example).
# '\1 ' => \1 is for the captured group (i.e. string that match the
# group ([.?!]) which is a single char in this case.), so it will add
# a space after the matched group.
If you are okay with getting rid of the squeeze statement then, using Nafaa's answer is the simplest way to do it but I've listed an alternate method in case its helpful:
string = string.split(" ").join(" ")
However, if you want to keep that squeeze statement you can amend Nafaa's method and use it after the squeeze statement:
string.gsub(/\s+/, ' ').gsub('. com', '.com')
or just directly change the string:
string.gsub('. com', '.com')

What is the best way to delimit a csv files thats contain commas and double quotes?

Lets say I have the following string and I want the below output without requiring csv.
this, "what I need", to, do, "i, want, this", to, work
this
what i need
to
do
i, want, this
to
work
This problem is a classic case of the technique explained in this question to "regex-match a pattern, excluding..."
We can solve it with a beautifully-simple regex:
"([^"]+)"|[^, ]+
The left side of the alternation | matches complete "quotes" and captures the contents to Group1. The right side matches characters that are neither commas nor spaces, and we know they are the right ones because they were not matched by the expression on the left.
Option 2: Allowing Multiple Words
In your input, all tokens are single words, but if you also want the regex to work for my cat scratches, "what I need", your dog barks, use this:
"([^"]+)"|[^, ]+(?:[ ]*[^, ]+)*
The only difference is the addition of (?:[ ]*[^, ]+)* which optionally adds spaces + characters, zero or more times.
This program shows how to use the regex (see the results at the bottom of the online demo):
subject = 'this, "what I need", to, do, "i, want, this", to, work'
regex = /"([^"]+)"|[^, ]+/
# put Group 1 captures in an array
mymatches = []
subject.scan(regex) {|m|
$1.nil? ? mymatches << $& : mymatches << $1
}
mymatches.each { |x| puts x }
Output
this
what I need
to
do
i, want, this
to
work
Reference
How to match (or replace) a pattern except in situations s1, s2, s3...
Article about matching a pattern unless...

Ruby: Remove whitespace chars at the beginning of a string

Edit: I solved this by using strip! to remove leading and trailing whitespaces as I show in this video. Then, I followed up by restoring the white space at the end of each string the array by iterating through and adding whitespace. This problem varies from the "dupe" as my intent is to keep the whitespace at the end. However, strip! will remove both the leading and trailing whitespace if that is your intent. (I would have made this an answer, but as this is incorrectly marked as a dupe, I could only edit my original question to include this.)
I have an array of words where I am trying to remove any whitespace that may exist at the beginning of the word instead of at the end. rstrip! just takes care of the end of a string. I want whitespaces removed from the beginning of a string.
example_array = ['peanut', ' butter', 'sammiches']
desired_output = ['peanut', 'butter', 'sammiches']
As you can see, not all elements in the array have the whitespace problem, so I can't just delete the first character as I would if all elements started with a single whitespace char.
Full code:
words = params[:word].gsub("\n", ",").delete("\r").split(",")
words.delete_if {|x| x == ""}
words.each do |e|
e.lstrip!
end
Sample text that a user may enter on the form:
Corn on the cob,
Fibonacci,
StackOverflow
Chat, Meta, About
Badges
Tags,,
Unanswered
Ask Question
String#lstrip (or String#lstrip!) is what you're after.
desired_output = example_array.map(&:lstrip)
More comments about your code:
delete_if {|x| x == ""} can be replaced with delete_if(&:empty?)
Except you want reject! because delete_if will only return a different array, rather than modify the existing one.
words.each {|e| e.lstrip!} can be replaced with words.each(&:lstrip!)
delete("\r") should be redundant if you're reading a windows-style text document on a Windows machine, or a Unix-style document on a Unix machine
split(",") can be replaced with split(", ") or split(/, */) (or /, ?/ if there should be at most one space)
So now it looks like:
words = params[:word].gsub("\n", ",").split(/, ?/)
words.reject!(&:empty?)
words.each(&:lstrip!)
I'd be able to give more advice if you had the sample text available.
Edit: Ok, here goes:
temp_array = text.split("\n").map do |line|
fields = line.split(/, */)
non_empty_fields = fields.reject(&:empty?)
end
temp_array.flatten(1)
The methods used are String#split, Enumerable#map, Enumerable#reject and Array#flatten.
Ruby also has libraries for parsing comma seperated files, but I think they're a little different between 1.8 and 1.9.
> ' string '.lstrip.chop
=> "string"
Strips both white spaces...

Resources