【问题标题】:Extracting the currency and price value from a string从字符串中提取货币和价格值
【发布时间】:2015-11-15 21:09:54
【问题描述】:

我正在尝试找到一种从字符串中提取货币和价格值的好方法。它应该适用于多种货币。零件……

  • 提取数字 - 可以是整数或十进制值
  • 检测附近的货币符号以将其与货币代码匹配
  • 忽略不是价格的数字 - 例如没有附加到货币指标

示例

  • “5.0 欧元的苹果、2 个橙子和草莓”
  • “5.0 欧元的苹果、32 个橙子和草莓”
  • “苹果、橙子 5 欧元和草莓”
  • “5 欧元的苹果、橙子和草莓”

结果

  • 价格为数字:5.0
  • 货币代码和符号:€ (EUR)

另一个例子

  • “5.0 美元的苹果、32 个橙子和草莓”→ 编号:5.0,货币 US$ (USD)

有什么好的方法可以处理不同的货币?

【问题讨论】:

  • 仅供参考 - $ 符号的用途远不止美元。加拿大人提到加元时只会写“$5.00”之类的东西。许多其他语言环境也会使用$ 作为当地货币。
  • 是的。对于实际转换,我可能会将提取的信息与来自[NSLocale currentLocale] 的信息结合起来

标签: ios objective-c swift


【解决方案1】:

您可以为此使用正则表达式。我在我的框架中使用以下内容:

class Regex {
  private let internalExpression: NSRegularExpression
  let pattern: String
  var groups:[String]? = nil

  init(_ pattern: String) {
    self.pattern = pattern
    let regex: NSRegularExpression?
    do {
      regex = try NSRegularExpression(pattern: pattern, options: .CaseInsensitive)
    } catch let error as NSError {
      fatalError("Invalid pattern '\(pattern)` (\(error))")
    }
    internalExpression = regex!
  }

  init(_ pattern: String, options: NSRegularExpressionOptions) {
    self.pattern = pattern
    let regex: NSRegularExpression?
    do {
      regex = try NSRegularExpression(pattern: pattern, options: options)
    } catch let error as NSError {
      fatalError("Invalid pattern '\(pattern)` (\(error))")
    }
    internalExpression = regex!
  }

  func test(input: String) -> Bool {
    let matches = self.internalExpression.matchesInString(input, options: [], range:NSMakeRange(0, input.characters.count)) as [NSTextCheckingResult]
    if matches.count == 0 { groups = nil; return false }
    if internalExpression.numberOfCaptureGroups > 0 {
      groups = [String]()
      let match = matches[0] as NSTextCheckingResult
      for index in 1..<match.numberOfRanges {
        let range = match.rangeAtIndex(index)
        if range.location == 9223372036854775807 { groups!.append("") }
        else { groups!.append((input as NSString).substringWithRange(range)) }
      }
    }
    return true
  }

  func match(index:Int) -> String? {
    return groups![index]
  }
}

然后你可以检查

let regexEuro = Regex("(\\d+(\\.\\d+)?) *€")
let regexDollar = Regex("\\$ *(\\d+(\\.\\d+)?)")
if regexEuro.test("This is 20 € ...") {
  print(regexEuro.match(0))
}
if regexDollar.test("This is $ 20.3 ...") {
  print(regexDollar.match(0))
}

【讨论】:

    【解决方案2】:

    Thomas 帖子中的 Regex 框架已更新到 Swift 4

    class Regex {
        private let regex: NSRegularExpression
        let pattern: String
        var groups: [String] = []
        init(_ pattern: String, options: NSRegularExpression.Options = []) throws {
            self.pattern = pattern
            regex = try NSRegularExpression(pattern: pattern, options: options)
        }
        func contains(string: String) -> Bool {
            groups = []
            let matches = regex.matches(in: string, options: [], range: NSMakeRange(0, string.utf16.count)) as [NSTextCheckingResult]
            guard !matches.isEmpty else {
                return false
            }
            if regex.numberOfCaptureGroups > 0,
            let firstMatch = matches.first {
                for index in 1..<firstMatch.numberOfRanges {
                    let range = firstMatch.range(at: index)
                    if range.location == .max {
                        groups.append("")
                    } else {
                        groups.append((string as NSString).substring(with: range))
                    }
                }
            }
            return true
        }
        func match(index: Int) -> String? {
            return groups[index]
        }
    }
    

    let regexEuro = try! Regex("(\\d+(\\.\\d+)?) *€")
    let regexDollar = try! Regex("\\$ *(\\d+(\\.\\d+)?)")
    if regexEuro.contains(string: "This costs 20€"),
        let value = regexEuro.match(index: 0) {
        print("Euro value:", value)  // "20\n"
    }
    
    if regexDollar.contains(string: "This costs $20.3"),
        let value = regexDollar.match(index: 0) {
        print("Dolar value:", value)  // "20.3\n"
    }
    

    【讨论】:

      猜你喜欢
      • 2019-09-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多