Zmieniło się to w Swift 2, zobacz nową odpowiedź przy użyciu nowego inicjalizatora awaryjnego Double (): stackoverflow.com/a/32850058/276626
Paul Solt
Odpowiedzi:
205
Swift 4.2+ String to Double
Powinieneś użyć inicjatorów nowego typu do konwersji między typami String i numerycznymi (Double, Float, Int). Zwróci typ opcjonalny (Double?), Który będzie miał poprawną wartość lub zero, jeśli ciąg nie był liczbą.
Uwaga: Właściwość NSString doubleValue nie jest zalecana, ponieważ zwraca 0, jeśli wartość nie może zostać przekonwertowana (tj. Złe dane wprowadzone przez użytkownika).
let lessPrecisePI =Float("3.14")let morePrecisePI =Double("3.1415926536")let invalidNumber =Float("alphabet")//nil, not a valid number
Rozpakuj wartości, aby użyć ich za pomocą if / let
iflet cost =Double(textField.text!){
print("The user entered a value price of \(cost)")}else{
print("Not a valid number: \(textField.text!)")}
Możesz konwertować sformatowane liczby i walutę za pomocą NumberFormatterklasy.
let formatter =NumberFormatter()
formatter.locale =Locale.current // USA: Locale(identifier: "en_US")formatter.numberStyle =.decimallet number = formatter.number(from:"9,999.99")
Formaty walutowe
let usLocale =Locale(identifier:"en_US")let frenchLocale =Locale(identifier:"fr_FR")let germanLocale =Locale(identifier:"de_DE")let englishUKLocale =Locale(identifier:"en_GB")// United Kingdomformatter.numberStyle =.currency
formatter.locale = usLocalelet usCurrency = formatter.number(from:"$9,999.99")
formatter.locale = frenchLocalelet frenchCurrency = formatter.number(from:"9999,99€")// Note: "9 999,99€" fails with grouping separator
// Note: "9999,99 €" fails with a space before the €
formatter.locale = germanLocalelet germanCurrency = formatter.number(from:"9999,99€")// Note: "9.999,99€" fails with grouping separator
formatter.locale = englishUKLocalelet englishUKCurrency = formatter.number(from:"£9,999.99")
Innym problemem jest to, że nie obsługuje liczb w różnych ustawieniach narodowych innych niż 1 000,00, jeśli użyjesz innych formatów, takich jak 1 000,00, odetnie 2 cyfry po przecinku na końcu. Przynajmniej tak dzieje się w przypadku Celu C. - Zgodnie z dokumentacją Apple: (Nie są one zgodne z ustawieniami regionalnymi) Poniższe metody wygody pomijają początkowe znaki spacji (whitespaceSet) i ignorują końcowe znaki. Nie są świadomi ustawień regionalnych. NSScanner lub NSNumberFormatter może być wykorzystywany do bardziej wydajnego i opartego na ustawieniach regionalnych analizowania liczb.
mskw
@mskw Dodałem dodatkowe szczegóły dotyczące korzystania z NumberFormatter do analizowania waluty. W moim kodzie połączę ze sobą wiele prób formatowania przy użyciu składni if / let, aby móc analizować zarówno liczby sformatowane w walucie (1 000,00 USD), jak i liczby sformatowane (1000). Nie zawsze wiesz, jak użytkownik wprowadzi liczby, więc możliwość obsługi obu jest idealna z grupą instrukcji if / let.
Paul Solt
276
Swift 2 Update
Są nowe inicjalizatory failable które pozwalają to zrobić w bardziej idiomatyczne i bezpieczny sposób (jak wiele odpowiedzi zauważyli, podwójna wartość NSString nie jest bardzo bezpieczne, ponieważ zwraca 0 dla wartości spoza numerycznych. Oznacza to, że doubleValueod "foo"i "0"są to samo.)
let myDouble =Double(myString)
Zwraca to wartość opcjonalną, więc w przypadkach takich jak przekazywanie w "foo"miejsce, w którym doubleValuezwróciłoby 0, zwracany jest niezawodny intializer nil. Można użyć guard, if-letlub mapdo obsługiOptional<Double>
Oryginalny post:
Nie musisz używać konstruktora NSString, jak proponuje zaakceptowana odpowiedź. Możesz po prostu to przełączyć w następujący sposób:
ohai, Jarsen. Wadą tego podejścia jest to, że nie zawiedzie, jeśli łańcuch nie będzie poprawnym podwójnym. Zamiast tego dostaniesz 0,0. Oznacza to, że wynik - [NSString doubleValue]jest Doubleszybki w zastosowaniu do Double?( Optional<Double>). Różni się to od funkcji Swift String, toInt()która zwraca Int?i stwierdza w dokumentach, że „... akceptuje ciągi pasujące do wyrażenia regularnego„ [- +]? [0-9] + ”tylko.”
Derrick Hathaway,
Tak, używanie .toInt()byłoby lepsze. Była to jednak raczej odpowiedź na to, jak zrobić dokładnie to samo, ale w Swift.
Jarsen
Takie podejście ściśle łączy Cię z Foundation i prawdopodobnie nie będzie działać na żadnych implementacjach Swift innych niż Apple.
Erik Kerber,
5
W Swift 2.0 dostępny jest Double.init?(_ text: String)teraz awaryjny inicjator.
mixel
3
To nie jest najlepsze podejście. Nie powiedzie się w zależności od separatora dziesiętnego. Będzie dobrze z „.” ale nie z „,”. NSNumberFormatter będzie obsługiwał separator dziesiętny używany w bieżącej lokalizacji.
Julian Król
75
Aby uzyskać nieco bardziej szybkie uczucie, użycie NSFormatter()unika rzutowania na NSStringi zwraca, nilgdy ciąg nie zawiera Doublewartości (np. „Test” nie zwróci 0.0).
let double =NSNumberFormatter().numberFromString(myString)?.doubleValue
Podoba mi się pomysł rozszerzenia klasy String dla aplikacji, które będą korzystać z konwersji w wielu miejscach. Ale nie widzę korzyści ze złożoności wywoływania NSNumberFormatter, ponieważ rzutowanie na NSString i używanie .doubleValue wydaje się co najmniej tak bezpośrednie, łatwiejsze do odczytania i zapamiętania.
wyczyść
12
W rzeczywistości zaletą użycia NSNumberFormatter () jest to, że metoda numberFromString: zwróci zero, jeśli ciąg znaków zawiera znaki, które nie tworzą podwójnej liczby. Problem z doubleValue na NSString polega na tym, że zawsze zwróci double (na przykład 0.0 dla „testu”) niezależnie od tego. Więc jeśli masz do czynienia z wszelkiego rodzaju ciągami znaków i chcesz sprawdzić, czy ciąg znaków jest podwójny, żadnych dodatkowych znaków, skorzystaj z NSNumberFormatter.
dirkgroten
4
Nie udaje się to po francusku.
Peter K.,
1
To świetne rozwiązanie, ale użycie tylko tego kodu nie będzie działać w krajach, w których przecinki są używane jako separatory (w tym Francja jako @PeterK. Wspomniane). Próbowałem napisać komentarz z rozwiązaniem, ale było to zbyt długo, więc zamiast tego musiałem udzielić odpowiedzi. Proszę bardzo: zmodyfikowane rozwiązanie
Jacob R
53
Inną opcją jest przekonwertowanie tego na NSStringi użycie tego:
let string =NSString(string: mySwiftString)
string.doubleValue
Chciałbym, żeby był to lepszy sposób. Skąd mam wiedzieć, na przykład, czy parsowanie się nie powiodło?
Ryan Hoffman
2
@RyanHoffman Niestety, umowa o podwójnej wartości NSString nigdy tego nie zapewniła. Otrzymasz tylko 0,0, jeśli ciąg nie rozpocznie się od prawidłowej reprezentacji liczby, OGROMNEJ_WARUNKU i -WIELKIEJ_WALNOŚCI w przypadku przepełnienia / niedopełnienia. Jeśli chcesz wiedzieć, dlaczego parsowanie nie powiodło się, uważam, że musisz przyjrzeć się NSNumberFormatter, który został zaprojektowany do obsługi konwersji liczb / ciągów w bardziej niezawodny sposób.
Jarsen
Ponieważ znalezienie tej odpowiedzi może być trudne, oto ona:(swiftString as NSString).doubleValue
LearnCocos2D,
24
Oto metoda rozszerzenia, która pozwala po prostu wywołać doubleValue () na łańcuchu Swift i uzyskać podwójne odwrócenie (przykładowe wyjście jest pierwsze)
extensionString{func doubleValue()->Double{let minusAscii:UInt8=45let dotAscii:UInt8=46let zeroAscii:UInt8=48var res =0.0let ascii =self.utf8var whole =[Double]()var current = ascii.startIndex
let negative = current != ascii.endIndex && ascii[current]== minusAscii
if(negative){
current = current.successor()}while current != ascii.endIndex && ascii[current]!= dotAscii
{
whole.append(Double(ascii[current]- zeroAscii))
current = current.successor()}//whole number
var factor:Double=1forvar i = countElements(whole)-1; i >=0; i--{
res +=Double(whole[i])* factor
factor *=10}//mantissa
if current != ascii.endIndex
{
factor =0.1
current = current.successor()while current != ascii.endIndex
{
res +=Double(ascii[current]- zeroAscii)* factor
factor *=0.1
current = current.successor()}}if(negative){
res *=-1;}return res
}}
Brak sprawdzania błędów, ale możesz go dodać, jeśli potrzebujesz.
Double.init?(_ text: String)stają się dostępne w Swift 2.0. Powinieneś o tym wspomnieć. Inne odpowiedzi tutaj nie są dlatego, że ludzie myślą jak programiści Objective-C, ale dlatego, że ten inicjator nie był wcześniej dostępny.
mixel
Rzeczywiście masz rację. Jest to dostępne tylko w Swift 2.0, wspomnę o tym :) Ale podobnie jak w innych językach inicjujesz typ z innym i nie powinieneś oczekiwać, że typ będzie w stanie przekonwertować na inny. Długa debata, ale jako programista Obj-C mam wiele złych praktyk podczas kodowania za pomocą Swift i to jest jedna z nich :)
Uwaga: - Jeśli ciąg znaków zawiera znaki inne niż cyfry lub separatory grupy lub liczby dziesiętne odpowiednie dla danego regionu, analiza nie powiedzie się. - Wszelkie początkowe lub końcowe znaki separatora spacji w ciągu są ignorowane. Na przykład ciągi „5”, „5” i „5” dają liczbę 5.
Nie widziałem odpowiedzi, której szukałem. Po prostu zamieszczam tutaj moje, na wypadek, gdyby to mogło pomóc każdemu. Ta odpowiedź jest ważna tylko wtedy, gdy nie potrzebujesz określonego formatu .
bridgeToObjectiveC () został usunięty w Xcode 6 Beta 5. Metoda pana Smileya jest najszybsza, jaką w tej chwili
znalazłem
7
Opiera się to na odpowiedzi @Ryu
Jego rozwiązanie jest świetne, dopóki jesteś w kraju, w którym kropki są używane jako separatory. Domyślnie NSNumberFormatterużywa ustawień regionalnych urządzeń. Dlatego nie powiedzie się to we wszystkich krajach, w których przecinek jest używany jako domyślny separator (w tym Francja, jak wspomniano @PeterK.), Jeśli liczba używa kropek jako separatorów (co zwykle ma miejsce). Aby ustawić ustawienia regionalne tego NSNumberFormatter na US, a zatem użyj kropek, ponieważ separatory zastępują linię
Metoda Apple'a zostanie nazwana .toDouble ... tak samo jak toInt. To dziwne pominięcie. Prawdopodobnie zostanie naprawiony w przyszłej wersji Swift. Najbardziej podoba mi się metoda rozszerzenia, utrzymanie kodu w czystości.
n13
Zwrócona
4
SWIFT 3
Aby wyczyścić, obecnie istnieje domyślna metoda:
public init?(_ text: String)z Doubleklasą.
Może być stosowany do wszystkich klas.
let c = Double("-1.0")let f = Double("0x1c.6")let i = Double("inf") itp.
// Init default Double variable
var scanned:Double()let scanner =NSScanner(string:"String to Scan")
scanner.scanDouble(&scanned)// scanned has now the scanned value if something was found.
Używanie Scannerw niektórych przypadkach jest bardzo wygodnym sposobem wydobywania liczb z łańcucha. I jest prawie tak potężny, jak w NumberFormatterprzypadku dekodowania i radzenia sobie z różnymi formatami liczb i lokalizacjami. Może wyodrębniać liczby i waluty z różnymi separatorami dziesiętnymi i grupowymi.
importFoundation// The code below includes manual fix for whitespaces (for French case)
let strings =["en_US":"My salary is $9,999.99","fr_FR":"Mon salaire est 9 999,99€","de_DE":"Mein Gehalt ist 9999,99€","en_GB":"My salary is £9,999.99"]// Just for referce
let allPossibleDecimalSeparators =Set(Locale.availableIdentifiers.compactMap({Locale(identifier: $0).decimalSeparator}))
print(allPossibleDecimalSeparators)for str in strings {let locale =Locale(identifier: str.key)let valStr = str.value.filter{!($0.isWhitespace || $0==Character(locale.groupingSeparator ??""))}
print("Value String", valStr)let sc =Scanner(string: valStr)// we could do this more reliably with `filter` as well
sc.charactersToBeSkipped =CharacterSet.decimalDigits.inverted
sc.locale = locale
print("Locale \(locale.identifier) grouping separator: |\(locale.groupingSeparator ?? "")| . Decimal separator: \(locale.decimalSeparator ?? "")")while!(sc.isAtEnd){iflet val = sc.scanDouble(){
print(val)}}}
Istnieją jednak problemy z separatorami, które można by traktować jako ograniczniki słów.
// This doesn't work. `Scanner` just ignores grouping separators because scanner tends to seek for multiple values
// It just refuses to ignore spaces or commas for example.
let strings =["en_US":"$9,999.99","fr_FR":"9999,99€","de_DE":"9999,99€","en_GB":"£9,999.99"]for str in strings {let locale =Locale(identifier: str.key)let sc =Scanner(string: str.value)
sc.charactersToBeSkipped =CharacterSet.decimalDigits.inverted.union(CharacterSet(charactersIn: locale.groupingSeparator ??""))
sc.locale = locale
print("Locale \(locale.identifier) grouping separator: \(locale.groupingSeparator ?? "") . Decimal separator: \(locale.decimalSeparator ?? "")")while!(sc.isAtEnd){iflet val = sc.scanDouble(){
print(val)}}}// sc.scanDouble(representation:Scanner.NumberRepresentation) could help if there were .currency case
Nie ma problemu z automatycznym wykryciem ustawień regionalnych. Zauważ, że groupingSeparator w języku francuskim w łańcuchu „Mon salaire est 9 999,99 €” nie jest spacją, chociaż może renderować się dokładnie jako spacja (tutaj nie ma). Właśnie dlatego poniższy kod działa dobrze bez !$0.isWhitespaceodfiltrowywania znaków.
let stringsArr =["My salary is $9,999.99","Mon salaire est 9 999,99€","Mein Gehalt ist 9.999,99€","My salary is £9,999.99"]let tagger =NSLinguisticTagger(tagSchemes:[.language], options:Int(NSLinguisticTagger.Options.init().rawValue))for str in stringsArr {
tagger.string = str
let locale =Locale(identifier: tagger.dominantLanguage ??"en")let valStr = str.filter{!($0==Character(locale.groupingSeparator ??""))}
print("Value String", valStr)let sc =Scanner(string: valStr)// we could do this more reliably with `filter` as well
sc.charactersToBeSkipped =CharacterSet.decimalDigits.inverted
sc.locale = locale
print("Locale \(locale.identifier) grouping separator: |\(locale.groupingSeparator ?? "")| . Decimal separator: \(locale.decimalSeparator ?? "")")while!(sc.isAtEnd){iflet val = sc.scanDouble(){
print(val)}}}//Also will fail if groupingSeparator == decimalSeparator (but don't think it's possible)
Błąd: ciąg „String” nie ma elementu o nazwie „doubleValue”
Matthew Knippen,
@Matthew Tak, nie ma członka o nazwie „podwójna wartość”, więc możemy użyć CDouble Value
ANIL.MUNDURU
1
en.wikipedia.org/wiki/... Odwołaj się do liczb zespolonych i przeczytaj dokumentację referencyjną Swift. Nie ma CDp2 ... Czy mówisz o Swift lub innym języku? Mam na myśli szybkie bez rozszerzeń?
Odpowiedzi:
Swift 4.2+ String to Double
Powinieneś użyć inicjatorów nowego typu do konwersji między typami String i numerycznymi (Double, Float, Int). Zwróci typ opcjonalny (Double?), Który będzie miał poprawną wartość lub zero, jeśli ciąg nie był liczbą.
Uwaga: Właściwość NSString doubleValue nie jest zalecana, ponieważ zwraca 0, jeśli wartość nie może zostać przekonwertowana (tj. Złe dane wprowadzone przez użytkownika).
Rozpakuj wartości, aby użyć ich za pomocą if / let
Możesz konwertować sformatowane liczby i walutę za pomocą
NumberFormatter
klasy.Formaty walutowe
Przeczytaj więcej na moim blogu o konwertowaniu ciągów znaków na podwójne (i walutę) .
źródło
Swift 2 Update Są nowe inicjalizatory failable które pozwalają to zrobić w bardziej idiomatyczne i bezpieczny sposób (jak wiele odpowiedzi zauważyli, podwójna wartość NSString nie jest bardzo bezpieczne, ponieważ zwraca 0 dla wartości spoza numerycznych. Oznacza to, że
doubleValue
od"foo"
i"0"
są to samo.)Zwraca to wartość opcjonalną, więc w przypadkach takich jak przekazywanie w
"foo"
miejsce, w którymdoubleValue
zwróciłoby 0, zwracany jest niezawodny intializernil
. Można użyćguard
,if-let
lubmap
do obsługiOptional<Double>
Oryginalny post: Nie musisz używać konstruktora NSString, jak proponuje zaakceptowana odpowiedź. Możesz po prostu to przełączyć w następujący sposób:
źródło
- [NSString doubleValue]
jestDouble
szybki w zastosowaniu doDouble?
(Optional<Double>
). Różni się to od funkcji Swift String,toInt()
która zwracaInt?
i stwierdza w dokumentach, że „... akceptuje ciągi pasujące do wyrażenia regularnego„ [- +]? [0-9] + ”tylko.”.toInt()
byłoby lepsze. Była to jednak raczej odpowiedź na to, jak zrobić dokładnie to samo, ale w Swift.Double.init?(_ text: String)
teraz awaryjny inicjator.Aby uzyskać nieco bardziej szybkie uczucie, użycie
NSFormatter()
unika rzutowania naNSString
i zwraca,nil
gdy ciąg nie zawieraDouble
wartości (np. „Test” nie zwróci0.0
).Alternatywnie, rozszerzając
String
typ Swift :i używaj go w następujący sposób
toInt()
:Zwraca to opcję opcjonalną,
Double?
którą należy rozpakować.Albo z wymuszonym rozpakowaniem:
lub z instrukcją if let:
Aktualizacja: W celu lokalizacji bardzo łatwo jest zastosować ustawienia narodowe do NSFormatter w następujący sposób:
Na koniec możesz użyć
NSNumberFormatterCurrencyStyle
formatyzatora, jeśli pracujesz z walutami, w których łańcuch zawiera symbol waluty.źródło
Inną opcją jest przekonwertowanie tego na
NSString
i użycie tego:źródło
(swiftString as NSString).doubleValue
Oto metoda rozszerzenia, która pozwala po prostu wywołać doubleValue () na łańcuchu Swift i uzyskać podwójne odwrócenie (przykładowe wyjście jest pierwsze)
Oto metoda rozszerzenia:
Brak sprawdzania błędów, ale możesz go dodać, jeśli potrzebujesz.
źródło
Począwszy od wersji Swift 1.1, można bezpośrednio przejść
String
doconst char *
parametru.Jeśli nie lubisz przestarzałych
atof
:Jedno zastrzeżenie: zachowanie konwersji jest inne niż
NSString.doubleValue
.atof
istrtod
zaakceptuj0x
poprzedzony ciąg szesnastkowy:Jeśli wolisz
.doubleValue
zachowanie, nadal możemy korzystać zCFString
mostkowania:źródło
NSString
.W Swift 2.0 najlepszym sposobem jest unikanie myślenia jak programista Objective-C. Dlatego nie powinieneś „konwertować ciągu na podwójny”, ale „inicjować podwójny z ciągu”. Dokument Apple tutaj: https://developer.apple.com/library/ios//documentation/Swift/Reference/Swift_Double_Structure/index.html#//apple_ref/swift/structctr/Double/s:FSdcFMSdFSSGSqSd_
Jest to opcjonalny init, więc możesz użyć zerowego operatora koalescencyjnego (??), aby ustawić wartość domyślną. Przykład:
źródło
Double.init?(_ text: String)
stają się dostępne w Swift 2.0. Powinieneś o tym wspomnieć. Inne odpowiedzi tutaj nie są dlatego, że ludzie myślą jak programiści Objective-C, ale dlatego, że ten inicjator nie był wcześniej dostępny.W SWIFT 3 możesz użyć:
Uwaga: - Jeśli ciąg znaków zawiera znaki inne niż cyfry lub separatory grupy lub liczby dziesiętne odpowiednie dla danego regionu, analiza nie powiedzie się. - Wszelkie początkowe lub końcowe znaki separatora spacji w ciągu są ignorowane. Na przykład ciągi „5”, „5” i „5” dają liczbę 5.
Zaczerpnięte z dokumentacji: https://developer.apple.com/reference/foundation/numberformatter/1408845-number
źródło
Nie widziałem odpowiedzi, której szukałem. Po prostu zamieszczam tutaj moje, na wypadek, gdyby to mogło pomóc każdemu. Ta odpowiedź jest ważna tylko wtedy, gdy nie potrzebujesz określonego formatu .
Szybki 3
źródło
Spróbuj tego:
UWAGA
Usunięto w wersji Beta 5. To już nie działa?
źródło
Opiera się to na odpowiedzi @Ryu
Jego rozwiązanie jest świetne, dopóki jesteś w kraju, w którym kropki są używane jako separatory. Domyślnie
NSNumberFormatter
używa ustawień regionalnych urządzeń. Dlatego nie powiedzie się to we wszystkich krajach, w których przecinek jest używany jako domyślny separator (w tym Francja, jak wspomniano @PeterK.), Jeśli liczba używa kropek jako separatorów (co zwykle ma miejsce). Aby ustawić ustawienia regionalne tego NSNumberFormatter na US, a zatem użyj kropek, ponieważ separatory zastępują linięz
Dlatego pełny kod staje się
Aby z tego skorzystać, wystarczy zadzwonić
"Your text goes here".toDouble()
Zwróci to opcjonalne
Double?
Jak wspomniano w @Ryu, możesz albo wymusić rozpakowanie:
lub użyj
if let
oświadczenia:źródło
NumberFormatter().number(from: myString)?.doubleValue
SWIFT 4
źródło
Swift 4.0
Spróbuj tego
źródło
Szybki: 4 i 5
Można to zrobić na dwa sposoby:
String -> Int -> Double:
String -> NSString -> Double
Używaj go w dowolny sposób, zgodnie z potrzebą kodu.
źródło
Sprawdź to na placu zabaw!
Przy okazji w moim Xcode
.toDouble () - nie istnieje
.doubleValue tworzy wartość 0.0 z ciągów nienumerycznych ...
źródło
1.
2)
Może ci to pomóc.
źródło
Jak już wspomniano, najlepszym sposobem na osiągnięcie tego jest rzutowanie bezpośrednie:
Opierając się na tym, możesz stworzyć eleganckie natywne rozszerzenie Swift String:
Pozwala to na bezpośrednie użycie:
Który wykona dla ciebie casting. Jeśli Apple doda
doubleValue
natywny ciąg, wystarczy usunąć rozszerzenie, a reszta kodu automatycznie się skompiluje!źródło
SWIFT 3
Aby wyczyścić, obecnie istnieje domyślna metoda:
public init?(_ text: String)
zDouble
klasą.Może być stosowany do wszystkich klas.
let c = Double("-1.0")
let f = Double("0x1c.6")
let i = Double("inf")
itp.źródło
Rozszerzenie z opcjonalnymi ustawieniami narodowymi
Swift 2.2
Swift 3.1
źródło
Lub możesz zrobić:
źródło
Możesz użyć StringEx . Rozciąga
String
się na konwersje ciągów na liczby, w tymtoDouble()
.Sprawdza ciąg i kończy się niepowodzeniem, jeśli nie można go przekonwertować na podwójny.
Przykład:
źródło
Szybki 4
źródło
Co również działa:
źródło
Użyj tego kodu w Swift 2.0
let strWithFloat = "78.65" let floatFromString = Double(strWithFloat)
źródło
Używanie
Scanner
w niektórych przypadkach jest bardzo wygodnym sposobem wydobywania liczb z łańcucha. I jest prawie tak potężny, jak wNumberFormatter
przypadku dekodowania i radzenia sobie z różnymi formatami liczb i lokalizacjami. Może wyodrębniać liczby i waluty z różnymi separatorami dziesiętnymi i grupowymi.Istnieją jednak problemy z separatorami, które można by traktować jako ograniczniki słów.
Nie ma problemu z automatycznym wykryciem ustawień regionalnych. Zauważ, że groupingSeparator w języku francuskim w łańcuchu „Mon salaire est 9 999,99 €” nie jest spacją, chociaż może renderować się dokładnie jako spacja (tutaj nie ma). Właśnie dlatego poniższy kod działa dobrze bez
!$0.isWhitespace
odfiltrowywania znaków.źródło
Bardziej czytelne wydaje się dodanie rozszerzenia do ciągu w następujący sposób:
i wtedy możesz po prostu napisać kod:
źródło
moim problemem był przecinek, więc rozwiązałem go w ten sposób:
źródło
źródło
możemy użyć wartości CDouble, która zostanie uzyskana przez myString.doubleValue
źródło