【问题标题】:How to trim a String using Swift 3如何使用 Swift 3 修剪字符串
【发布时间】:2017-06-15 13:34:21
【问题描述】:

我的代码 sn-p 是:

unwanted = " £€₹jetztabfromnow"

let favouritesPriceLabel = priceDropsCollectionView.cells.element(boundBy: UInt(index)).staticTexts[IPCUIAHighlightsPriceDropsCollectionViewCellPriceLabel].label
let favouritesPriceLabelTrimmed = favouritesPriceLabel.components(separatedBy: "jetzt").flatMap { String($0.trimmingCharacters(in: .whitespaces)) }.last

favouritesHighlightsDictionary[favouritesTitleLabel] = favouritesPriceLabelTrimmed

我的问题是,这不起作用:

let favouritesPriceLabelTrimmed = favouritesPriceLabel.components(separatedBy: unwanted).flatMap { String($0.trimmingCharacters(in: .whitespaces)) }.last

我的价格类似于“3,95 €” - 我想减少所有货币“£€₹”和“from”或“ab”之类的词

你有什么解决方案吗,我可以在这里使用什么?

【问题讨论】:

  • 这个字符串有固定的语言环境吗?
  • 无。它可以在更多语言环境之间更改。

标签: ios swift3 character-trimming


【解决方案1】:

与其尝试替换或删除正确的字符或使用正则表达式,我更愿意使用 Foundation 的内置语言标记支持。它将对字符串进行词法分析并返回各种类型的标记。在这种字符串上使用它,它应该可靠地找到字符串中的任何数字。

类似:

var str = "from 3,95 €"

let range = Range(uncheckedBounds: (lower: str.startIndex, upper: str.endIndex))

var tokenRanges = [Range<String.Index>]()

let scheme = NSLinguisticTagSchemeLexicalClass
let option = NSLinguisticTagger.Options()
let tags = str.linguisticTags(in: range, scheme: scheme, options: option, orthography: nil, tokenRanges: &tokenRanges)
let tokens = tokenRanges.map { str.substring(with:$0) }

if let numberTagIndex = tags.index(where: { $0 == "Number" }) {
    let number = tokens[numberTagIndex]
    print("Found number: \(number)")
}

在本例中,代码打印“3,95”。如果您将 str 更改为“28.50 英镑起”,则会打印“28.50”。

【讨论】:

  • 嗨,我测试你的版本。但我有一个问题。我想把你的版本放在一个辅助方法中。我有不止一个价格要检查和修剪,分布在几个地方。我怎样才能从测试中移交给助手并再次返回以进一步使用它来获得结果。是否可以将其更改为双精度?
  • 我不确定我是否理解。听起来您想创建一个包含此代码的func,并将字符串作为参数。从func 返回语言分析的结果。字符串可以转换成数字类型,所以函数可以返回数字而不是字符串。
【解决方案2】:

一种方法是将不需要的字符串放入一个数组中,并使用 String 的replacingOccurrences(of:with:) 方法。

let stringToScan = "£28.50"
let toBeRemoved = ["£", "€", "₹", "ab", "from"]
var result = stringToScan
toBeRemoved.forEach { result = result.replacingOccurrences(of: $0, with: "") }
print(result)

...产生“28.50”。

【讨论】:

    【解决方案3】:

    如果你只是想提取数值使用正则表达式,它会考虑逗号或点小数分隔符。

    let string = "from 3,95 €"
    
    let pattern = "\\d+[.,]\\d+"
    do {
        let regex = try NSRegularExpression(pattern: pattern, options: [])
        if let match = regex.firstMatch(in: string, range: NSRange(location: 0, length: string.utf16.count)) {
            let range = match.range
            let start = string.index(string.startIndex, offsetBy: range.location)
            let end = string.index(start, offsetBy: range.length)
            print(string.substring(with: start..<end)) // 3,95
        } else {
            print("Not found")
        }
    } catch {
        print("Regex Error:", error)
    }
    

    【讨论】:

      【解决方案4】:

      我问你是否有这个字符串的固定语言环境,因为这样你就可以使用语言环境来确定小数分隔符是什么:例如,在故事板中试试这个。

      let string = "some initial text 3,95 €" // define the string to scan
      
      // Add a convenience extension to Scanner so you don't have to deal with pointers directly.
      extension Scanner {
          func scanDouble() -> Double? {
              var value = Double(0)
              guard scanDouble(&value) else { return nil }
              return value
          }
      
          // Convenience method to advance the location of the scanner up to the first digit. Returning the scanner itself or nil, which allows for optional chaining
          func scanUpToNumber() -> Scanner? {
              var value: NSString?
              guard scanUpToCharacters(from: CharacterSet.decimalDigits, into: &value) else { return nil }
              return self
          }
      }
      
      let scanner = Scanner(string: string)
      scanner.locale = Locale(identifier: "fr_FR")
      let double = scanner.scanUpToNumber()?.scanDouble() // -> double = 3.95 (note the type is Double?)
      

      在这些情况下,扫描器比 NSRegularExpressions 更容易使用。

      【讨论】:

      • 对不起,我今天看到了,你问的。无,可以在更多区域之间更改,例如(FR、IT、DE、UK、ES 和 IN(英国))
      【解决方案5】:

      您可以通过删除alphanumerics来按特殊字符过滤。

      extension String {
      
          func removeCharacters(from forbiddenChars: CharacterSet) -> String {
              let passed = self.unicodeScalars.filter { !forbiddenChars.contains($0) }
              return String(String.UnicodeScalarView(passed))
          }
      }
      
      let str = "£€₹jetztabfromnow12"
      
      let t1 = str.removeCharacters(from: CharacterSet.alphanumerics)
      print(t1) // will print: £€₹
      
      let t2 = str.removeCharacters(from: CharacterSet.decimalDigits.inverted)
      print(t2) // will print: 12
      

      更新 1:

      var str = "£3,95SS"
      
      str = str.replacingOccurrences(of: ",", with: "")
      
      let digit = str.removeCharacters(from: CharacterSet.decimalDigits.inverted)
      print(digit) // will print: 395
      
      let currency = str.removeCharacters(from: CharacterSet.alphanumerics)
      print(currency) // will print: £
      
      let amount = currency + digit
      print(amount) // will print: £3,95
      

      更新 2:

      let string = "£3,95SS"
      
      let pattern = "-?\\d+(,\\d+)*?\\.?\\d+?"
      do {
          let regex = try NSRegularExpression(pattern: pattern, options: [])
          if let match = regex.firstMatch(in: string, range: NSRange(location: 0, length: string.utf16.count)) {
              let range = match.range
              let start = string.index(string.startIndex, offsetBy: range.location)
              let end = string.index(start, offsetBy: range.length)
              let digit = string.substring(with: start..<end)
              print(digit) //3,95
      
              let symbol = string.removeCharacters(from: CharacterSet.symbols.inverted)
              print(symbol) // £
      
              print(symbol + digit) //£3,95
      
          } else {
              print("Not found")
          }
      } catch {
          print("Regex Error:", error)
      }
      

      【讨论】:

      • 好的,如果我打印 (t1),我将获得 £€₹,但我想获得 3,95
      • 你想只得到数字吗?更新了我的答案以从字符串中获取数字
      • 当数字为 3,95 时会起作用吗?它会删除小数点/逗号吗?
      • 好的,我怎样才能把字符串放在我得到价格的地方?请参阅上面的示例... favouritesPriceLabelTrimmed 是带有完整字符串的字符串,例如“from 3,95 €” 它应该放在哪里 let t2 = str.removeCharacters(from: CharacterSet.decimalDigits.inverted)
      • 工作,但你有没有想法把它作为一个 Double 而不是作为一个字符串数字返回?如果我这样做:let favouritesPriceLabelTrimmed = favouritesPriceLabel.removeCharacters(from: CharacterSet.decimalDigits.inverted).toDouble(with: favouritesPriceLabel) 我会继续:favouritesHighlightsDictionary[favouritesTitleLabel] = favouritesPriceLabelTrimmed 一个错误:“对成员的歧义引用”
      猜你喜欢
      • 1970-01-01
      • 2011-02-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-06-22
      • 1970-01-01
      • 2017-05-24
      • 2022-01-01
      相关资源
      最近更新 更多