신속하게 문자열에서 숫자가 아닌 모든 문자를 제거하십시오.


84

숫자 값이어야하지만 공백이나 기타 영숫자가 아닌 문자를 포함 할 수있는 일부 알려지지 않은 데이터를 구문 분석해야합니다.

Swift에서이 작업을 수행하는 새로운 방법이 있습니까? 내가 온라인에서 찾을 수있는 것은 일을하는 오래된 C 방식 인 것 같다.

내가보고 있어요 stringByTrimmingCharactersInSet- 나는 확실히 내 입력은 문자열의 시작 또는 끝에서 공백 / 특수 문자를해야합니다 생각한다. 이를 위해 사용할 수있는 내장 문자 세트가 있습니까? 아니면 직접 만들어야합니까?

stringFromCharactersInSet()유지할 유효한 문자 만 지정할 수 있는 것과 같은 것이 있기를 바랐습니다.

답변:


183

유지할 유효한 문자 만 지정할 수있는 stringFromCharactersInSet () 같은 것이 있기를 바랐습니다.

문자 세트 trimmingCharacters와 함께 사용 inverted하여 문자열의 시작 또는 끝에서 문자를 제거 할 수 있습니다 . Swift 3 이상 :

let result = string.trimmingCharacters(in: CharacterSet(charactersIn: "0123456789.").inverted)

또는 문자열에서 숫자가 아닌 문자를 제거하려면 (시작 또는 끝이 아닌)를 사용할 수 있습니다 filter. characters예를 들어 Swift 4.2.1에서 :

let result = string.filter("0123456789.".contains)

또는 문자열의 어느 곳에서나 CharacterSet에서 문자를 제거하려면 다음을 사용하십시오.

let result = String(string.unicodeScalars.filter(CharacterSet.whitespaces.inverted.contains))

또는 특정 형식 (예 :)의 유효한 문자열 만 일치 시키려면 ####.##정규식을 사용할 수 있습니다. 예를 들면 :

if let range = string.range(of: #"\d+(\.\d*)?"#, options: .regularExpression) {
    let result = string[range] // or `String(string[range])` if you need `String`
}

이러한 다른 접근 방식의 동작은 약간 다르므로 수행하려는 작업에 따라 다릅니다. 10 진수 또는 정수만 원하는 경우 소수점을 포함하거나 제외합니다. 이를 수행하는 방법에는 여러 가지가 있습니다.


이전 Swift 2 구문 의 경우이 답변의 이전 개정판을 참조하십시오 .


invertedSwift 3 예제에서 문자 집합 을 처리해야하는 이유를 설명해 주 시겠습니까?
Andy Ibanez

4
@AndyIbanez "ABC"가 내가 유지하고 싶은 캐릭터라면 "ABC"가 아닌 모든 것을 다듬는 것과 같습니다.
Scott McKenzie

1
Swift 4.2.1에서는 다음 let result = String(string.characters.filter { "01234567890.".characters.contains($0) })으로 단축 될 수 있습니다.let result = string.filter("01234567890.".contains)
Leo Dabus 2019

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

스위프트 3

let result = string.replacingOccurrences( of:"[^0-9]", with: "", options: .regularExpression)

이 답변을 찬성 할 수 있습니다 .


3
감사! 모든 Swift3 변경 사항을 적용한 후 myStr.replacingOccurrences (of : "[^ 0-9]", with : "", options : .regularExpression)
bobwki

29

나는 확장 기능을 좋아하기 때문에이 솔루션을 선호 하고 나에게 조금 더 깨끗해 보입니다. 여기에 재현 된 솔루션 :

extension String {
    var digits: String {
        return components(separatedBy: CharacterSet.decimalDigits.inverted)
            .joined()
    }
}

스트립 소수 보인다
markturnip

18

Swift 4

문자열에서 영숫자 만 설정 하는 적절한 방법을 찾았습니다 . 예를 들면 :-

func getAlphaNumericValue() {

    var yourString  = "123456789!@#$%^&*()AnyThingYouWant"

    let unsafeChars = CharacterSet.alphanumerics.inverted  // Remove the .inverted to get the opposite result.  

    let cleanChars  = yourString.components(separatedBy: unsafeChars).joined(separator: "")


    print(cleanChars)  // 123456789AnyThingYouWant

}

17

범위에 대해 패턴 일치 연산자를 사용하여 문자열의 UnicodeScalarView를 필터링하고 0에서 9까지 UnicodeScalar ClosedRange를 전달하고 결과 UnicodeScalarView로 새 문자열을 초기화 할 수 있습니다.

extension String {
    private static var digits = UnicodeScalar("0")..."9"
    var digits: String {
        return String(unicodeScalars.filter(String.digits.contains))
    }
}

"abc12345".digits   // "12345"

편집 / 업데이트 :

스위프트 4.2

extension RangeReplaceableCollection where Self: StringProtocol {
    var digits: Self {
        return filter(("0"..."9").contains)
    }
}

또는 돌연변이 방법으로

extension RangeReplaceableCollection where Self: StringProtocol {
    mutating func removeAllNonNumeric() {
        removeAll { !("0"..."9" ~= $0) }
    }
}

Swift 5.2 • Xcode 11.4 이상

Swift5에서는 다음과 같은 새로운 Character 속성을 사용할 수 있습니다 isWholeNumber.

extension RangeReplaceableCollection where Self: StringProtocol {
    var digits: Self { filter(\.isWholeNumber) }
}

extension RangeReplaceableCollection where Self: StringProtocol {
    mutating func removeAllNonNumeric() {
        removeAll { !$0.isWholeNumber }
    }
}

마침표도 허용하기 위해 Character를 확장하고 계산 된 속성을 만들 수 있습니다.

extension Character {
    var isDecimalOrPeriod: Bool { "0"..."9" ~= self || self == "." }
}

extension RangeReplaceableCollection where Self: StringProtocol {
    var digitsAndPeriods: Self { filter(\.isDecimalOrPeriod) }
}

놀이터 테스트 :

"abc12345".digits   // "12345"

var str = "123abc0"
str.removeAllNonNumeric()
print(str) //"1230"

"Testing0123456789.".digitsAndPeriods // "0123456789."

Swift 5를위한 훌륭한 솔루션! "."를 어떻게 떠날 수 있습니까? 또는 ","문자열 내에서 문자열을 Double로 변환 할 수 있습니까?
Hans Bondoka

1
@HansBondoka 감사합니다 filter { $0.isNumber || $0 == "." }.
Leo Dabus

11

filter기능을 이용한 솔루션rangeOfCharacterFromSet

let string = "sld [f]34é7*˜µ"

let alphaNumericCharacterSet = NSCharacterSet.alphanumericCharacterSet()
let filteredCharacters = string.characters.filter {
  return  String($0).rangeOfCharacterFromSet(alphaNumericCharacterSet) != nil
}
let filteredString = String(filteredCharacters) // -> sldf34é7µ

숫자 만 필터링하려면 다음을 사용하십시오.

let string = "sld [f]34é7*˜µ"

let numericSet = "0123456789"
let filteredCharacters = string.characters.filter {
  return numericSet.containsString(String($0))
}
let filteredString = String(filteredCharacters) // -> 347

또는

let numericSet : [Character] = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]
let filteredCharacters = string.characters.filter {
  return numericSet.contains($0)
}
let filteredString = String(filteredCharacters) // -> 347

나는 어떤 알파 값도 원하지 않지만 아무 것도 기대하지 않습니다
Dan

좀 더 구체적으로 말씀해주세요. 제목에 non-alphanumeric;-) 숫자에 대한 답을 편집했습니다.
vadian 2011-04-13

8

스위프트 4

그러나 확장이나 componentSeparatedByCharactersInSet는 읽지 않습니다.

let allowedCharSet = NSCharacterSet.letters.union(.whitespaces)
let filteredText = String(sourceText.unicodeScalars.filter(allowedCharSet.contains))

4

Swift 3, 숫자를 제외한 모든 필터링

let myString = "dasdf3453453fsdf23455sf.2234"
let result = String(myString.characters.filter { String($0).rangeOfCharacter(from: CharacterSet(charactersIn: "0123456789")) != nil })
print(result)

3

스위프트 4.2

let numericString = string.filter { (char) -> Bool in
    return char.isNumber
}

2

이런 식으로 할 수 있습니다 ...

let string = "[,myString1. \"" // string : [,myString1. " 
let characterSet = NSCharacterSet(charactersInString: "[,. \"")
let finalString = (string.componentsSeparatedByCharactersInSet(characterSet) as NSArray).componentsJoinedByString("") 
print(finalString)   
//finalString will be "myString1"

문자열에 어떤 문자가 포함될 수 있는지 완전히 알지 못하며 끝에 숫자 값만 원합니다. 내가 원하지 않는 모든 문자를 나열해야합니다. 그럴 수있는 많은 문자가 있습니다
Dan

2

Rob의 첫 번째 솔루션의 문제 stringByTrimmingCharactersInSet는 Apple의 문서에 명시된대로 전체가 아닌 문자열 끝만 필터링하는 것입니다.

주어진 문자 세트에 포함 된 수신자 문자의 양쪽 끝에서 제거하여 만든 새 문자열을 반환합니다.

대신 사용 componentsSeparatedByCharactersInSet하여 먼저 문자 집합의 모든 비 발생을 배열로 분리 한 다음 빈 문자열 구분 기호로 결합합니다.

"$$1234%^56()78*9££".componentsSeparatedByCharactersInSet(NSCharacterSet(charactersInString: "0123456789").invertedSet)).joinWithSeparator("")

어떤 반환 123456789


사용할 필요가 없습니다 NSCharacterSet. 그러나 당신의 대답은 최고입니다. 다음은 일반 버전입니다.extension String { func removingCharactersNot(in charSet: CharacterSet) -> String { return self.components(separatedBy: charSet.inverted).joined(separator: "") } }
xaphod

2

스위프트 3

extension String {
    var keepNumericsOnly: String {
        return self.components(separatedBy: CharacterSet(charactersIn: "0123456789").inverted).joined(separator: "")
    }
}

2
let string = "+1*(234) fds567@-8/90-"
let onlyNumbers = string.components(separatedBy: CharacterSet.decimalDigits.inverted).joined()

print(onlyNumbers) // "1234567890"

또는

extension String {

  func removeNonNumeric() -> String {
    return self.components(separatedBy: CharacterSet.decimalDigits.inverted).joined()
  }
}

let onlyNumbers = "+1*(234) fds567@-8/90-".removeNonNumeric() 
print(onlyNumbers)// "1234567890"

1

Swift 4.0 버전

extension String {
    var numbers: String {
        return String(describing: filter { String($0).rangeOfCharacter(from: CharacterSet(charactersIn: "0123456789")) != nil })
    }
}

1

스위프트 4

String.swift

import Foundation

extension String {

    func removeCharacters(from forbiddenChars: CharacterSet) -> String {
        let passed = self.unicodeScalars.filter { !forbiddenChars.contains($0) }
        return String(String.UnicodeScalarView(passed))
    }

    func removeCharacters(from: String) -> String {
        return removeCharacters(from: CharacterSet(charactersIn: from))
    }
}

ViewController.swift

let character = "1Vi234s56a78l9"
        let alphaNumericSet = character.removeCharacters(from: CharacterSet.decimalDigits.inverted)
        print(alphaNumericSet) // will print: 123456789

        let alphaNumericCharacterSet = character.removeCharacters(from: "0123456789")
        print("no digits",alphaNumericCharacterSet) // will print: Vishal

새로운 UnicodeScalarView를 초기화하는 것은 의미가 없습니다. 필터의 결과는 이미 UnicodeScalarView입니다. return String(passed)
Leo Dabus 2017

1

스위프트 4.2

let digitChars  = yourString.components(separatedBy:
        CharacterSet.decimalDigits.inverted).joined(separator: "")

0

Swift 3 버전

extension String
{
    func trimmingCharactersNot(in charSet: CharacterSet) -> String
    {
        var s:String = ""
        for unicodeScalar in self.unicodeScalars
        {
            if charSet.contains(unicodeScalar)
            {
                s.append(String(unicodeScalar))
            }
        }
        return s
    }
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.