我一直在使用正则表达式来查找字符串中的不同模式,这种方法还可以,但是我失去了出现顺序。
例如,当我检查这个字符串:10£ + 5$ / 4EUR
时,我会检查是否有符号和/或ISO代码,并在旁边进行一些额外的工作,最终返回一个数组。但它并没有按照出现顺序排序。
查找所有货币的主要方法
def find_currencies(string)
currencies = []
# check symbols
currencies = currencies + currencies_from_symbol(string) if string =~ /\p{Sc}/
# check iso codes
if Currency.iso_codes.any? { |code| string =~ /#{code}/i }
iso_codes = string.scan(Regexp.new(Currency.iso_codes.join('|'), true))
currencies = currencies + iso_codes.map { |code| Money::Currency.find(code.downcase.to_sym) }
end
currencies
end
从货币符号返回货币的方法
def currencies_from_symbol(string)
currencies = Money::Currency.all.select do |m|
string.scan(/\p{Sc}/).include?(m.symbol) && m.priority < 10
end
unless currencies.any? { |m| m.id == :usd || m.id == :gbp }
return currencies
end
# Default to USD and GBP
# TODO: Remove when default can be selected
currencies.select { |m| m.id == :usd || m.id == :gbp }
end
find_currencies
将返回以下结果:[#<Money::Currency id: usd>, #<Money::Currency id: gbp>, #<Money::Currency id: eur>]
,这与字符串原始顺序不符。我需要它变成 [gbp, usd, eur]
。我真的很感激你的帮助。我目前的想法是同时查找符号和 ISO 代码,以保留出现顺序。但是,当然分开做会更好。
require 'money'; Money.assume_from_symbol = true; str.split.map { |s| Money.parse(s) }.compact
。我安装了Money并发现Money::new
和其他方法可用,但是parse
似乎需要安装(某些部分的)Rails。由于我不知道Rails,因此无法测试。(请尝试并在评论中报告结果。)我假设如果字符串无法解析,则parse
返回nil
。如果它引发异常,则必须捕获并返回nil
。 - Cary SwovelandMoney
已经停止支持字符串解析,该功能已转移到Monetize
gem中,我正在使用它。但它并不够复杂,还有待探索。 - Maxim Fedotov