4

I am able to extract numbers using below code:

let weightt = x.components(separatedBy: CharacterSet.decimalDigits.inverted).joined(separator: "")

For example, I'm getting "01" from string "0.1kg"

But how to extract "0.1" from string "0.1kg" ?

2
  • Is the number always at the start of the string or can the number be anywhere in the string? Commented Jul 20, 2017 at 5:57
  • 1
    And you should update your question with several examples of strings you need to process. Different solutions may not work for all possible input you need to handle. Commented Jul 20, 2017 at 6:02

5 Answers 5

2

You can use

Input

 let x = "0.1kg"

let weightt = x.components(separatedBy: CharacterSet.init(charactersIn: "0123456789.").inverted).joined(separator: "")

output

 0.1
Sign up to request clarification or add additional context in comments.

5 Comments

This doesn't localize well. French for instance uses spaces and commas in formatted numbers, let alone other languages that use non-western digit characters.
@BenLachman may be you are right but I have answered as per question asked You are free to update my answer if you have better solution I will appreciate it. Or later on I will update it as for now I am on vacation :)
Using Scanner is the correct solution. While this works for the single case in the original question, there are a huge number of cases where it doesn't work at all (ex. "$1.56")
@BenLachman I have answered as per user question requirement. If you inject other scenarios that are out of the scope. so requested you to remove your downvote.
The point isn't to answer the exact question. The point is to give a good solution that takes into account the larger questions of good software engineering. Adding as much knowledge as possible per answer should always be the goal.
2

A good approach is to use Scanner. Example:

let string = " 0.1 kg"
let scanner = Scanner.localizedScanner(with: string)

var weight = 0.0
if scanner.scanDouble(&weight) {
    print(weight) // 0.1
}

The scanDouble()/scanFloat() methods parse all kinds of floating point notations (+12.34, -56.78, 1.23e4, 1,23, etc.), skip initial whitespace, support multiple locales, and scan as much as possible from the given string.

4 Comments

This is the correct answer and supports correct behavior in other regions/languages.
This seems very elegant. But how do you scan for the next number in a string? Can you tell the scanner to advance to the next number?
i dont get it. why is there a string variable and then a weight? i thought string would be the one that's going to be parsed. then there's a weight variable? what for
@chitgoks: string is the String variable containing the string to be parsed, here " 0.1 kg". The parse result is stored in the weight variable, which has the type Double.
0

Try this also :

let str = "0.1kg"
let decimal = str.components(separatedBy: CharacterSet.init(charactersIn: "0123456789.").inverted).first.flatMap { Float($0) }
print(decimal ?? "")

Comments

0

Use

let result = weightt.stringByReplacingOccurrencesOfString("kg", withString: "")

If you want to remove all characters from weightt use code. Means if it is gm instead of kg.

let result = string.stringByReplacingOccurrencesOfString("[^A-Za-z]", withString: "", 
options: NSStringCompareOptions.RegularExpressionSearch, range:nil).stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceCharacterSet())

1 Comment

Your regular expression isn't valid. Did you mean "[^A-Za-z]" to find anything that isn't a letter?
0

You didn't say anything about the constraints of the input, so I assume it is a valid decimal number followed by a unit.

You can use prefix to do this if that's the case:

let weight = "0.1kg"
let result = String(weight.characters.prefix {
     "012346789.".characters.contains($0)) })

2 Comments

Using .description for anything but debug output always feels a bit of a code smell to me (and the exact description format is not guaranteed officially). You can achieve the same with String(weight.characters.prefix { "012346789.".characters.contains($0) })
@MartinR Edited. Thank you!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.