Say I have a string like this
"some3random5string8"
I want to insert spaces after each integer so it looks like this
"some3 random5 string8"
I specifically want to do this using gsub but I can't figure out how to access the characters that match my regexp.
For example:
temp = "some3random5string8"
temp.gsub(/\d/, ' ') # instead of replacing with a ' ' I want to replace with
# matching number and space
I was hoping there was a way to reference the regexp match. Something like $1 so I could do something like temp.gsub(/\d/, "#{$1 }") (note, this does not work)
Is this possible?
From the gsub 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, where n is a
group name. If it is a double-quoted string, both back-references must
be preceded by an additional backslash.
This means the following 3 versions will work
>> "some3random5string8".gsub(/(\d)/, '\1 ')
=> "some3 random5 string8 "
>> "some3random5string8".gsub(/(\d)/, "\\1 ")
=> "some3 random5 string8 "
>> "some3random5string8".gsub(/(?<digit>\d)/, '\k<digit> ')
=> "some3 random5 string8 "
Edit: also if you don't want to add an extra space at the end, use a negative lookahead for the end of line, e.g.:
>> "some3random5string8".gsub(/(\d(?!$))/, '\1 ')
=> "some3 random5 string8"
A positive lookahead checking for a "word character" would also work of course:
>> "some3random5string8".gsub(/(\d(?=\w))/, '\1 ')
=> "some3 random5 string8"
Last but not least, the simplest version without a space at the end:
>> "some3random5string8".gsub(/(\d)(\w)/, '\1 \2')
=> "some3 random5 string8"
gsubtakes a block, which for me is easier to remember than the block-less way of getting the match.
"some3random5string8".gsub(/\d/){|digit| digit << " "}
Not sure about ruby syntax, but:
temp.gsub(/(\d)/, '$1 ')
or
temp.gsub(/(\d)/, '\1 ')
To be sure you insert space between number and a non number(i.e. letter or special char):
temp.gsub(/(\d)(\D)/, '$1 $2')
I am not very familiar with ruby, but I expect you can capture the digit, and then insert into replacement like this...
temp.gsub(/(\d)/, '$1 ')
Related
I want to transform " - " string in Ruby to being translatable to regexp. I need to have something like that:
my_regexp => "\s?-\s?"
However, I have a problem with special characters: This "\s" character isn't shown correctly. I tried few ways. Without success.
INPUT => OUTPUT
"\s?" => " ?"
"\\s?" => "\\s?"
Have you any idea how to solve that?
\\ is just a escaped \.
If you print, puts it, you will see the actual string.
>> '\s' # == "\\s"
=> "\\s"
>> puts '\s'
\s
=> nil
BTW, "\s" (not '\s') is another representation of whitespace " ":
>> "\s" == " "
=> true
Most likely, what you're seeing is the result of how IRB displays values. Your second example is correct, (the actual result only contains a single slash, which you can confirm by creating a new Regexp object from it):
>> "\\s?"
"\\s?"
>> puts "\\s?"
\s?
>> Regexp.new "\\s?"
/\s?/
How do I add a space after a certain amount of numbers?
If i have the number 02920555555 and wanted to add a space after the fifth number only, how would I go about that? Could I do this with a gsub and a regular expression? I would like to put it in a helper:
def area_code(tel)
tel.gsub()
end
Thanks
Just use the insert method:
'02920555555'.insert(5, ' ')
# => "02920 555555"
Use '\& ' as replacement string. (\& represents the matched string)
'02920555555'.gsub(/\d{4}/, '\& ')
# => "0292 0555 555"
UPDATE
to add a space after the 5th number only, use sub instead of gsub:
'02920555555'.sub(/\d{5}/, '\& ')
# => "02920 555555"
or using gsub with the pattern ^... (matches only at the beginning of the input string):
'02920555555'.gsub(/^\d{5}/, '\& ')
# => "02920 555555"
If you don't feel comfortable with regex then you can use the insert method:
'123456789'.insert(5, ' ')
The first parameter for the insert method is the position, (the index at which you want to insert) and second parameter is for the character that you want to insert.
So, our code is saying take number 123456789 and insert space at index 5.
output:
"12345 6789"
'0292055555'.gsub(/(\d{5})(\d*)/, "\\1 \\2")
# => 02920 55555
I am saving a price string to my database in a decimal-type column.
The price comes in like this "$ 123.99" which is fine because I wrote a bit of code to remove the "$ ".
However, I forgot that the price may include a comma, so "$ 1,234.99" breaks my code. How can I also remove the comma?
This is my code to remove dollar sign and space:
def price=(price_str)
write_attribute(:price, price_str.sub("$ ", ""))
# possible code to remove comma also?
end
You can get there two ways easily.
String's delete method is good for removing all occurrences of the target strings:
'$ 1.23'.delete('$ ,') # => "1.23"
'$ 123,456.00'.delete('$ ,') # => "123456.00"
Or, use String's tr method:
'$ 1.23'.tr('$, ', '') # => "1.23"
'$ 123,456.00'.tr('$ ,', '') # => "123456.00"
tr takes a string of characters to search for, and a string of characters used to replace them. Consider it a chain of gsub methods, one for each character.
BUT WAIT! THERE'S MORE! If the replacement string is empty, all characters in the search string will be removed.
I have a string and I need to check whether the last character of that string is *, and if it is, I need to remove it.
if stringvariable.include? "*"
newstring = stringvariable.gsub(/[*]/, '')
end
The above does not search if the '*' symbol is the LAST character of the string.
How do i check if the last character is '*'?
Thanks for any suggestion
Use the $ anchor to only match the end of line:
"sample*".gsub(/\*$/, '')
If there's the possibility of there being more than one * on the end of the string (and you want to replace them all) use:
"sample**".gsub(/\*+$/, '')
You can also use chomp (see it on API Dock), which removes the trailing record separator character(s) by default, but can also take an argument, and then it will remove the end of the string only if it matches the specified character(s).
"hello".chomp #=> "hello"
"hello\n".chomp #=> "hello"
"hello\r\n".chomp #=> "hello"
"hello\n\r".chomp #=> "hello\n"
"hello\r".chomp #=> "hello"
"hello \n there".chomp #=> "hello \n there"
"hello".chomp("llo") #=> "he"
"hello*".chomp("*") #=> "hello"
String has an end_with? method
stringvariable.chop! if stringvariable.end_with? '*'
You can do the following which will remove the offending character, if present. Otherwise it will do nothing:
your_string.sub(/\*$/, '')
If you want to remove more than one occurrence of the character, you can do:
your_string.sub(/\*+$/, '')
Of course, if you want to modify the string in-place, use sub! instead of sub
Cheers,
Aaron
You can either use a regex or just splice the string:
if string_variable[-1] == '*'
new_string = string_variable.gsub(/[\*]/, '') # note the escaped *
end
That only works in Ruby 1.9.x...
Otherwise you'll need to use a regex:
if string_variable =~ /\*$/
new_string = string_variable.gsub(/[\*]/, '') # note the escaped *
end
But you don't even need the if:
new_string = string_variable.gsub(/\*$/, '')
I have an array of stop words:
myArray = ["","a","ago","also","am","an","and","ani","ar","aren't","arent","as","ask","at","did","didn't","didnt","do","doe","would","be","been","best","better"]
I would like to remove matching items from a sentence:
str = 'A something and hello'
So it becomes:
'something hello'
1. How can I do that in ruby?
2. How could I also do it for an array of characters (which removes all matching characters)?
Here's the array of characters:
["(",")","#","#","^"]
sentence = 'A something and hello'
array = ["","a","ago","also","am","an","and","ani","ar","aren't","arent",
"as","ask","at","did","didn't","didnt","do","doe","would",
"be","been","best","better"]
sentence.split.delete_if{|x| array.include?(x)}.join(' ')
=> "A something hello"
you might want to downcase all words before comparison, to get rid of the "A" in the beginning of the sentence:
sentence.split.delete_if{|x| array.include?(x.downcase)}.join(' ')
=> "something hello"
if you have an array of strings, it's easier:
(sentence.split - array).join(' ')
=> "A something hello" # but note that this doesn't catch the "A"
to also delete the special characters:
special = ["(",")","#","#","^"]
sentence.split.delete_if{|x| array.include?(x.downcase) || special.include?(x) }.join(' ')
another approach to delete words or phrases is:
array.each do |phrase|
sentence.gsub!(/#{phrase}/,'')
end
A one-line variant of Tilo's answer that is clean and case-insensitive (although it returns all lowercase output, which may not be ideal for all uses):
(sentence.downcase.split - array).join(' ')
array.map {|s| s.gsub(keyword, '')}
My solution:
stop_words = ["","a","ago","also","am","an","and","ani","ar","aren't","arent","as","ask","at","did","didn't","didnt","do","doe","would","be","been","best","better"]
output = %w(A something and hello) - stop_words