2015-04-02 15 views
24

Jak uzyskać ciąg przed pewną postacią w szybkim tempie? Poniższy kod jest taki, jak zrobiłem to w Celu C, ale nie mogę wykonać tego samego zadania w Swift. Wszelkie wskazówki lub sugestie, jak to osiągnąć? rangeOfString wydaje się nie działać wcale w szybkim tempie (chociaż Swift znowu działa dla mnie).Swift: Jak uzyskać ciąg przed określoną postacią?

NSRange range = [time rangeOfString:@" "]; 
NSString *startDate = 
[time substringToIndex:range.location]; 

Jak widać z kodu powyżej jestem w stanie uzyskać ciąg przed znak spacji w Objective C

Edit: Gdy próbuję coś takiego

var string = "hello Swift" 
var range : NSRange = string.rangeOfString("Swift") 

I uzyskać następujący błąd.

nie można przekonwertować typu wyrażenia za 'NSString' wpisać '(String, opcje: NSStringCompareOptions, zakres: Zakres ?, locale:? NSLocale)'

Nie wiem co zrobiłem źle dokładnie lub jak rozwiązać to poprawnie.

+0

W [ta odpowiedź] (http: //przepełnienie stosu.com/a/24161872/2240769) również używają rangeOfString w Swift i wydaje się działać. –

+0

Edytowałem moje pytanie, aby lepiej wyjaśnić, co się dzieje, gdy próbuję zastosować twoje rozwiązanie. –

+0

Możesz użyć 'Range' zamiast' NSRange': 'let range: Range? = string.rangeOfString ("Swift") '. Możesz również rzucić 'String' na' NSString': 'var range: NSRange = (ciąg znaków jako NSString) .rangeOfString (" Swift ")' – albertamg

Odpowiedz

56

Zastosowanie componentsSeparatedByString(), jak pokazano poniżej:

var delimiter = " " 
var newstr = "token0 token1 token2 token3" 
var token = newstr.componentsSeparatedByString(delimiter) 
print (token[0]) 

Albo używać konkretny przypadek:

var delimiter = " token1" 
var newstr = "token0 token1 token2 token3" 
var token = newstr.componentsSeparatedByString(delimiter) 
print (token[0]) 

Swift 3 EDIT:

Z Swift 3 powyższej metody już nie działa, użyj zamiast tego:

var token = newstr.components(separatedBy: delimiter) 

Jeśli ta zmiana pomogła, prześlij wiadomość na temat this answer.

+0

Fantastyczna odpowiedź. Próbowałem dowiedzieć się, jak wykonać to zadanie w/rangeOfString, ale jest to DUŻO bardziej wydajne. – Adrian

15

Można zrobić to samo z rangeOfString() dostarczone przez String klasy

let string = "Hello Swift" 
if let range = string.rangeOfString("Swift") { 
    let firstPart = string[string.startIndex..<range.startIndex] 
    print(firstPart) // print Hello 
} 

Można również osiągnąć go z metodą substringToIndex()

let string = "Hello Swift" 
if let range = string.rangeOfString("Swift") { 
    firstPart = string.substringToIndex(range.startIndex) 
    print(firstPart) // print Hello 
} 

Swift 3 UPDATE:

let string = "Hello Swift" 
if let range = string.range(of: "Swift") { 
    let firstPart = string[string.startIndex..<range.lowerBound] 
    print(firstPart) // print Hello 
} 

Nadzieja ta może pomóc;)

3

Jeśli chcesz rozwiązanie, które nie wiąże się ciągnąc w fundacji, można to zrobić z find i krojenie:

let str = "Hello, I must be going." 

if let comma = find(str, ",") { 
    let substr = str[str.startIndex..<comma] 
    // substr will be "Hello" 
} 

Jeśli wyraźnie chcą pusty ciąg w przypadku, gdy nie zostanie znaleziony taki charakter, można użyć operatora zero-koalescencyjny:

let str = "no comma" 
let comma = find(str, ",") ?? str.startIndex 
let substr = str[str.startIndex..<comma] // substr will be "" 

Uwaga, w przeciwieństwie do techniki componentsSeparatedByString, nie wymaga tworzenia tablicy i onl y wymaga skanowania do pierwszego wystąpienia znaku, zamiast rozbijania całego ciągu znaków na tablicę rozdzielaną znakami.

+0

tak ... działa ... ale co jeśli chcę uzyskać ciąg po określonej postaci? –

+0

@Bhavin 'find (str,", ")? Successor()' –

+2

@all 'find' jest ** już nie ** obsługiwany w Swift 2.0 – Honey

1

Można użyć rangeOfString, ale zwraca Range<String.Index> typ, a nie NSRange:

let string = "hello Swift" 
if let range = string.rangeOfString("Swift") { 
    print(string.substringToIndex(range.startIndex)) 
} 
2

mutować ciąg na części do pierwszego pojawienia się określonego ciągu można przedłużyć ciąg tak:

extension String { 

    mutating func until(_ string: String) { 
     var components = self.components(separatedBy: string) 
     self = components[0] 
    } 

} 

można to nazwać jak to wówczas:

var foo = "Hello Swift" 
foo.until(" Swift") // foo is now "Hello" 
0

Moje 2 centów :-) użyciu Swift 3.0, podobnego do PHP strstr

extension String { 

    func strstr(needle: String, beforeNeedle: Bool = false) -> String? { 
     guard let range = self.range(of: needle) else { return nil } 

     if beforeNeedle { 
      return self.substring(to: range.lowerBound) 
     } 

     return self.substring(from: range.upperBound) 
    } 

} 

Usage1

"Hello, World!".strstr(needle: ",", beforeNeedle: true) // returns Hello 

Usage2

"Hello, World!".strstr(needle: " ") // returns World! 
3

Nawiązując do odpowiedzi Syed Tarika: Jeśli chcesz tylko ciąg przed ogranicznikiem (w przeciwnym razie y ou otrzymać tablicę [String]):

var token = newstr.components(separatedBy: delimiter).first 
+0

To działało dla mnie. Dzięki. – waseefakhtar

1
let string = "Hello-world" 
if let range = string.range(of: "-") { 
let firstPart = string[(string.startIndex)..<range.lowerBound] 
print(firstPart) 
} 

wyjścia: Witam

0

poniżej jest rodzajem całego combo

let string = "This a string split using * and this is left." 
if let range = string.range(of: "*") { 
    let lastPartIncludingDelimiter = string.substring(from: range.lowerBound) 
    print(lastPartIncludingDelimiter) // print * and this is left. 

    let lastPartExcludingDelimiter = string.substring(from: range.upperBound) 
    print(lastPartExcludingDelimiter) // print and this is left. 

    let firstPartIncludingDelimiter = string.substring(to: range.upperBound) 
    print(firstPartIncludingDelimiter) // print This a string split using * 

    let firstPartExcludingDelimiter = string.substring(to: range.lowerBound) 
    print(firstPartExcludingDelimiter) // print This a string split using 
} 
Powiązane problemy