问题描述
我有一个始终会转换为this之类的字符串,在该字符串中,用户输入数字并始终以小数点开头,
所以我有0.01-> 0.10-> 1.00
这是我现有的将100000转换为1,000.00的代码
func convertme(string: String) -> String{
var number: NSNumber!
let formatter = NumberFormatter()
formatter.numberStyle = .currencyAccounting
formatter.currencySymbol = ""
formatter.maximumFractionDigits = 2
formatter.minimumFractionDigits = 2
var amountWithPrefix = string
// remove from String: "$",".",","
let regex = try! NSRegularExpression(pattern: "[^0-9]",options: .caseInsensitive)
amountWithPrefix = regex.stringByReplacingMatches(in: amountWithPrefix,options: NSRegularExpression.MatchingOptions(rawValue: 0),range: NSMakeRange(0,string.count),withTemplate: "")
print("amountWithPrefix",amountWithPrefix)
let double = (amountWithPrefix as Nsstring).doubleValue
number = NSNumber(value: (double / 100))
// if first number is 0 or all numbers were deleted
guard number != 0 as NSNumber else {
return ""
}
return formatter.string(from: number)!
}
预期结果:
我想设置字符串格式的数字而不添加其他数据,我想将(100000.变成100,000。)(100000.0变成100,000.0
我希望将我的100000转换为100,000,并且如果用户也输入了十进制,则只能有一个十进制,因此当用户输入100000.00时,它将转换为100,000.00。
PS。我那里有一个正则表达式,只接受数字但不接受小数,如何使它也接受小数?
解决方法
您可以简单地从原始字符串中过滤非数字或句点,尝试将结果字符串强制为整数。如果成功,则将格式化程序的最大分数位数设置为零,否则将最大分数位数设置为2并将字符串强制为双精度:
extension Formatter {
static let currency: NumberFormatter = {
let formatter = NumberFormatter()
formatter.locale = .init(identifier: "en_US_POSIX")
formatter.numberStyle = .currencyAccounting
formatter.currencySymbol = ""
return formatter
}()
}
extension Numeric {
var currencyUS: String {
Formatter.currency.string(for: self) ?? ""
}
}
func convertme(string: String) -> String {
let string = string.filter("0123456789.".contains)
if let integer = Int(string) {
Formatter.currency.maximumFractionDigits = 0
return Formatter.currency.string(for: integer) ?? "0"
}
Formatter.currency.maximumFractionDigits = 2
return Double(string)?.currencyUS ?? "0"
}
convertme(string: "100000") // "100,000"
convertme(string: "100000.00") // "100,000.00"
编辑/更新: “ 100,000。”这不是有效的数字格式。您需要手动在字符串末尾插入句点。
func convertme(string: String) -> String {
var string = string.filter("0123456789.".contains)
// this makes sure there is only one period and keep only the last one in the string
while let firstIndex = string.firstIndex(of: "."),let _ = string[firstIndex...].dropFirst().firstIndex(of: ".") {
string.remove(at: firstIndex)
}
// get the index of the period in your string
if let index = string.firstIndex(of: ".") {
// get the fraction digits count and set the number formatter appropriately
let fractionDigits = string[index...].dropFirst().count
Formatter.currency.minimumFractionDigits = fractionDigits
Formatter.currency.maximumFractionDigits = fractionDigits
// Number Formatter wont add a period at the end of the string if there is no fractional digits then you need to manually add it yourself
if fractionDigits == 0 {
return (Double(string)?.currencyUS ?? "0") + "."
}
} else {
// in case there is no period set the fraction digits to zero
Formatter.currency.minimumFractionDigits = 0
Formatter.currency.maximumFractionDigits = 0
}
return Double(string)?.currencyUS ?? "0"
}
游乐场测试:
convertme(string: "100000") // "100,000"
convertme(string: "100000.") // "100,000."
convertme(string: "100000.0") // "100,000.0"
convertme(string: "100000.00") // "100,000.00"
convertme(string: "100000.000") // "100,000.000"