I want to change the default numbers from english to arabic when the user switches to the arabic interface.
13 => ١٣
89 => ٨٩
What is the best way to tackle this problem?
I add in helper module
ARABIC_NUMBERS = %w(٠ ١ ٢ ٣ ٤ ٥ ٦ ٧ ٨ ٩)
def ta numbers
numbers = numbers.to_s if numbers.is_a? Integer
results = numbers.chars.map { |char| ARABIC_NUMBERS[char.to_i] }.join
end
Check this code : https://github.com/gdotdesign/rails-arabic-convert/blob/master/app/helpers/convert_helper.rb.
It's a helper to convert a english number to an arabic number.
I came up with this quick solution. I added the following function in the ApplicationHelper
def tn(num)
num.to_s.split(//).map{|r|t("n"+r)}.join
end
Then added translations for each number from 0 to 9 in the config/locals/ar.yml with the format below:
n1: "١"
n2: "٢"
n3: "٣"
.
.
.
Now we can call the new numeric translation function by tn(13) which will output ١٣ in arabic localization
Related
Is there any in built method in ruby which will generate unique alphabetic string every time(it should not have numbers only alphabets)?
i have tried SecureRandom but it doesn't provide method which will return string containing only alphabets.
SecureRandom has a method choose which:
[...] generates a string that randomly draws from a source array of characters.
Unfortunately it's private, but you can call it via send:
SecureRandom.send(:choose, [*'a'..'z'], 8)
#=> "nupvjhjw"
You could also monkey-patch Random::Formatter:
module Random::Formatter
def alphabetic(n = 16)
choose([*'a'..'z'], n)
end
end
SecureRandom.alphabetic
#=> "qfwkgsnzfmyogyya"
Note that the result is totally random and therefore not necessarily unique.
UUID are designed to have extremely low chance of collision. Since UUID only uses 17 characters, it's easy to change the non-alphabetic characters into unused alphabetic slots.
SecureRandom.uuid.gsub(/[\d-]/) { |x| (x.ord + 58).chr }
Is there any in built method in ruby which will generate unique alphabetic string every time(it should not have numbers only alphabets)?
This is not possible. The only way that a string can be unique if you are generating an unlimited number of strings is if the string is infinitely long.
So, it is impossible to generate a string that will be unique every time.
def get_random_string(length=2)
source=("a".."z").to_a + ("A".."Z").to_a
key=""
length.times{ key += source[rand(source.size)].to_s }
key
end
How about something like this if you like some monkey-patching, i have set length 2 here , please feel free to change it as per your needs
get_random_string(7)
I used Time in miliseconds, than converted it into base 36 which gives me unique aplhanumeric value and since it depends on time so, it will be very unique.
Example: Time.now.to_f.to_s.gsub('.', '').ljust(17, '0').to_i.to_s(36) # => "4j26m4zm2ss"
Take a look at this for full answer: https://stackoverflow.com/a/72738840/7365329
Try this one
length = 50
Array.new(length) { [*"A".."Z", *"a".."z"].sample }.join
# => bDKvNSySuKomcaDiAlTeOzwLyqagvtjeUkDBKPnUpYEpZUnMGF
I'm using Rails and Nokogiri and I'm trying to parse some website.
This is where I'm stuck:
doc.css('#example > li:nth-child(1)').each do |node|
money = node.xpath('//*ul/li/div/span').text
end
It returns something like:
$100,000£230,000$40,000$9,000€600$800,000
I want to split those items, save them to the database and finally hand them to the view.
So, in the view, I want it to appear like:
(1)$100,000
(2)£230,000
(3)$40,000
(4)$9,000
(5)€600
(6)$800,000
I tried to split those items by this code below.
money = node.xpath('//*ul/li/div/span').text.split(/[$€£]/)
but the result looks like this:
["", "100,000", "230,000", "40,000", "9,000", "600", "800,000"]
And I don't know which item is in Dollar, Euro, or Pond.
Is there any good way to solve this problem?
you're almost there,
just use the positive lookahead :)
irb(main):005:0> "$100,000£230,000$40,000$9,000€600$800,000".split(/(?=[$£€])/)
=> ["$100,000", "£230,000", "$40,000", "$9,000", "€600", "$800,000"]
It needs a regular expression. This works:
"$100,000£230,000$40,000$9,000$600$800,000".scan(/([^\d][0-9,]+)/)
=> [["$100,000"],
["£230,000"],
["$40,000"],
["$9,000"],
["$600"],
["$800,000"]]
The regex contains these parts:
[^\d]: A character class matching a single non-digit. This will match the currency symbol.
`[0-9,]+': Another character class, this time repeating (the '+'). It matches the numeric part (0-9) plus the thousand's separator.
This method extract browser language and is working fine when the language have 2 letter, es, en, de...etc.
def extract_locale_from_accept_language_header
browser_locale = request.env['HTTP_ACCEPT_LANGUAGE'].try(:scan, /^[a-z]{2}/).try(:first).try(:to_sym)
if I18n.available_locales.include? browser_locale
browser_locale
else
I18n.default_locale
end
end
However is not working when the browser language have 4 letters:
en
en-us
en-gb
en-au
en-ca
zh-TW
zh-cn
How can fix this problem?
Thanks
Your regular expression is only looking for two letters try this:
browser_locale = request.env['HTTP_ACCEPT_LANGUAGE'].try(:scan, /^[a-z-]{2,5}/).try(:first).try(:to_sym)
This will work with two to five character codes with lower case letters or dashes.
This is just a start you may need to refine this regular expression more.
Here is a ruby gem which does exactly what you want:
languages = HTTP::Accept::Language.parse("da, en-gb;q=0.8, en;q=0.7")
expect(languages[0].locale).to be == "da"
expect(languages[1].locale).to be == "en-gb"
expect(languages[2].locale).to be == "en"
It has 100% test coverage on a wide range of inputs.
How would I detect if I have this scenario, I would be getting this inputs
3b => allow
4b => allow
55b => allow
1111bbbb => allow
num45 => no !
and if I do allow given, I wold also like to remove all characters that are not numbers
3b => 3
555B => 555
11 => 11
I have tried to check if the given input is numeric or not, but this condition is out of scope of my knowledge.
Thanks for your time and consideration.
You can use:
/\A(\d+)[a-z]*\z/i
If the expression matches your desired number will be in the first capturing group.
Example at Rubular. (It uses ^/$ instead of \A/\z just for the demonstration, you should use \A/\z.)
This will look for integer + string and convert it to an integer. It will ignore a string + integer input.
input = '45num'
if input.match(/\d+[a-zA-Z]+/)
result = input.to_i
end
result => 45
You really want to use: str[/\A\d+/] - This will give you the leading digits or nil.
Hmm I am no regex ninja but I think you could use: ^([\d]+) to capture JUST the number. give it a try here
if the string begins with a number
!/^[0-9]/.match(#variable).nil?
if it does, get only the number part
#variable = #variable.gsub(/[^0-9]/, '')
I have a stories text field and want to show the first few lines – say the first 50 words of that field – in a snapshot page. How can I do that in Ruby (on Rails)?
Assuming your words are delimited by a space, you can do something like this.
stories.split(' ').slice(0,50).join(' ')
Mostly the same as Aaron Hinni's answer, but will try and keep 3 full sentences (then truncate to 50 words, if it's the sentences were too long)
def truncate(text, max_sentences = 3, max_words = 50)
# Take first 3 setences (blah. blah. blah)
three_sentences = text.split('. ').slice(0, max_sentences).join('. ')
# Take first 50 words of the above
shortened = three_sentences.split(' ').slice(0, max_words).join(' ')
return shortened # bah, explicit return is evil
end
Also, if this text has any HTML, my answer on "Truncate Markdown?" might be of use
In use something very similar in a Rails application to extend ("monkey patch") the base String class.
I created lib/core_extensions.rb which contains:
class String
def to_blurb(word_count = 30)
self.split(" ").slice(0, word_count).join(" ")
end
end
I then created config/initializers/load_extensions.rb which contains:
require 'core_extensions'
Now I have the to_blurb() method on all my String objects in the Rails application.