आप String.substringWithRange का उपयोग कैसे करते हैं? (या, रंग स्विफ्ट में कैसे काम करते हैं?)


266

मैं अभी तक यह पता लगाने में सक्षम नहीं हूं कि Stringस्विफ्ट में ए का विकल्प कैसे मिलेगा :

var str =Hello, playground”
func test(str: String) -> String {
 return str.substringWithRange( /* What goes here? */ )
}
test (str)

मैं स्विफ्ट में रेंज बनाने में सक्षम नहीं हूं। खेल के मैदान में स्वत: पूर्ण सुपर सहायक नहीं है - यह वह है जो यह सुझाव देता है:

return str.substringWithRange(aRange: Range<String.Index>)

मुझे स्विफ्ट स्टैंडर्ड रेफरेंस लाइब्रेरी में कुछ भी नहीं मिला है जो मदद करता है। यहाँ एक और जंगली अनुमान था:

return str.substringWithRange(Range(0, 1))

और इस:

let r:Range<String.Index> = Range<String.Index>(start: 0, end: 2)
return str.substringWithRange(r)

मैंने अन्य उत्तर देखे हैं ( स्विफ्ट स्ट्रिंग में चरित्र का पता लगाना ) जो यह बताता है कि चूंकि Stringएक पुल प्रकार है NSString, "पुराने" तरीकों से काम करना चाहिए, लेकिन यह स्पष्ट नहीं है कि कैसे - जैसे, यह या तो काम नहीं करता है ( मान्य सिंटैक्स प्रतीत नहीं होता है):

let x = str.substringWithRange(NSMakeRange(0, 3))

विचार?


जब आप कहते हैं कि अंतिम उदाहरण काम नहीं करता है तो आपका क्या मतलब है? क्या यह त्रुटि का कारण बनता है या अप्रत्याशित मान लौटाता है?
67

कृपया डुबकी लगाएं rdar: // 17158813 सबस्क्रिप्ट नोटिफ़िकेशन का अनुरोध करें openradar.appspot.com/radar?id=6373877630369792
रोब नेपियर

जवाबों:


259

आप substringWithRange पद्धति का उपयोग कर सकते हैं। यह एक शुरुआत और अंत String.Index लेता है।

var str = "Hello, playground"
str.substringWithRange(Range<String.Index>(start: str.startIndex, end: str.endIndex)) //"Hello, playground"

प्रारंभ और अंत इंडेक्स को बदलने के लिए, उन्नतबी (एन) का उपयोग करें।

var str = "Hello, playground"
str.substringWithRange(Range<String.Index>(start: str.startIndex.advancedBy(2), end: str.endIndex.advancedBy(-1))) //"llo, playgroun"

आप अभी भी NSRange के साथ NSString विधि का उपयोग कर सकते हैं, लेकिन आपको यह सुनिश्चित करना होगा कि आप जैसे NSString का उपयोग कर रहे हैं:

let myNSString = str as NSString
myNSString.substringWithRange(NSRange(location: 0, length: 3))

नोट: जैसा कि JanX2 ने उल्लेख किया है, यह दूसरी विधि यूनिकोड स्ट्रिंग्स के साथ सुरक्षित नहीं है।


5
हाँ। अभी के लिए मैं जब आवश्यक हो NSString के लिए जारी रहेगा। ऐसा लगता है कि स्विफ्ट का स्ट्रिंग अभी भी अधूरा है
कॉनर

14
यह सुरक्षित नहीं है! आप मान रहे हैं कि स्ट्रिंग और NSString में अनुक्रमित विनिमेय हैं। बात वह नहीं है। एक स्ट्रिंग में अनुक्रमित यूनिकोड कोड बिंदुओं को संदर्भित करता है जबकि एक NSString में अनुक्रमित UTF-16 कोड इकाइयों को संदर्भित करता है! इसे इमोजी के साथ आज़माएं।
JanX2

3
कृपया ध्यान दें कि एक स्ट्रिंग में अनुक्रमित अब यूनिकोड कोड बिंदुओं का उल्लेख नहीं करते हैं। उन्हें उपयोगकर्ता-कथित पात्रों को संदर्भित करने के रूप में सोचें।
JanX2

2
तो यहाँ सही उत्तर क्या है? कॉलिंग का advanceमतलब है कि हमें संभवतः लंबे स्ट्रिंग के माध्यम से पूरे रास्ते को पुनरावृत्त करना होगा। लेकिन NSRange बनाना और NSString का स्पष्ट रूप से उपयोग करना खतरनाक है? क्या बाकि है?
मैट

1
धन्यवाद, एम m स्विफ्ट के लिए यह संक्रमण केवल 4 साल के बाद गड़बड़ करने जैसा है।
फेलिप

162

स्विफ्ट 2

सरल

let str = "My String"
let subStr = str[str.startIndex.advancedBy(3)...str.startIndex.advancedBy(7)]
//"Strin"

स्विफ्ट 3

let startIndex = str.index(str.startIndex, offsetBy: 3)
let endIndex = str.index(str.startIndex, offsetBy: 7)

str[startIndex...endIndex]       // "Strin"
str.substring(to: startIndex)    // "My "
str.substring(from: startIndex)  // "String"

स्विफ्ट 4

substring(to:)और substring(from:)में पदावनत कर रहे हैं Swift 4

String(str[..<startIndex])    // "My "
String(str[startIndex...])    // "String"
String(str[startIndex...endIndex])    // "Strin"

2
यह। इसलिए भ्रमित करना कि आपको इसका उपयोग करने से पहले अपना सूचकांक ढूंढना होगा। पता नहीं क्यों मुझे महसूस करने में इतना लंबा समय लगा, लेकिन मानव प्रकार में आपके योगदान के लिए धन्यवाद।
वारपजीत

1
स्विफ्ट 4 में सबस्ट्रिंग ऑपरेशन्स स्ट्रींग के बजाय सबस्ट्रिंग प्रकार का एक उदाहरण देते हैं। परिणाम को दीर्घकालिक भंडारण के लिए स्ट्रिंग में बदलने की आवश्यकता है। let newString = स्ट्रिंग (
स्थानापन्न

43

नोट :: @airspeedswift इस दृष्टिकोण के व्यापार-नापसंद पर विशेष रूप से छिपे हुए प्रदर्शन प्रभावों पर कुछ बहुत ही व्यावहारिक बिंदु बनाता है । स्ट्रिंग्स सरल जानवर नहीं हैं, और किसी विशेष इंडेक्स पर पहुंचने में O (n) समय लग सकता है, जिसका अर्थ है कि एक लूप जो सबस्क्रिप्ट का उपयोग करता है वह O (n ^ 2) हो सकता है। आपको चेतावनी दी गई है।

आपको बस एक नया subscriptफ़ंक्शन जोड़ने की आवश्यकता है जो एक सीमा लेता है और advancedBy()जहां आप चाहते हैं वहां चलने के लिए उपयोग करता है:

import Foundation

extension String {
    subscript (r: Range<Int>) -> String {
        get {
            let startIndex = self.startIndex.advancedBy(r.startIndex)
            let endIndex = startIndex.advancedBy(r.endIndex - r.startIndex)

            return self[Range(start: startIndex, end: endIndex)]
        }
    }
}

var s = "Hello, playground"

println(s[0...5]) // ==> "Hello,"
println(s[0..<5]) // ==> "Hello"

(यह निश्चित रूप से भाषा का हिस्सा होना चाहिए। कृप्या rdar: // 17158813 )

मज़े के लिए, आप एक +ऑपरेटर को अनुक्रमित पर भी जोड़ सकते हैं :

func +<T: ForwardIndex>(var index: T, var count: Int) -> T {
  for (; count > 0; --count) {
    index = index.succ()
  }
  return index
}

s.substringWithRange(s.startIndex+2 .. s.startIndex+5)

(मुझे अभी तक नहीं पता है कि यह भाषा का हिस्सा होना चाहिए या नहीं।)


2
हमें संभवतः प्रदर्शन कारणों के लिए पूर्णांक अनुक्रमितों के बजाय String.Index के साथ काम करना चाहिए। एक पूर्णांक सूचकांक से एक String.Index में हर रूपांतरण की तलाश करने के लिए स्ट्रिंग को संसाधित करने की आवश्यकता होती है।
JanX2

11
@AndrewDunn यह समयपूर्व अनुकूलन नहीं है। एक पूर्णांक सूचकांक से एक String.Index में प्रत्येक रूपांतरण O (n) है, O (1) नहीं! कृपया नामस्थान advance<T>(…)में टिप्पणियों के लिए पढ़ें Swift
JanX2

1
स्ट्रिंग कार्यान्वयन का पूरा उपयोग करके किया जाता है String.Index। इस मामले में यह उतना अनुकूलन नहीं है क्योंकि यह सब कुछ सीधा रख रहा है। Int और String.Index के बीच हर जगह आगे और पीछे घूमने के कारण गड़बड़ हो जाएगी।
चक्र

@chakrit केवल अगर अनुक्रमणिका का उपयोग करने की आवश्यकता है, तो पहले से ही पूर्णांक नहीं हैं (बजाय होने के String.Index) जो अक्सर होता है। बस आप उन सभी स्ट्रिंग हैंडलिंग विधियों को कामना कर सकते हैं जो Intएस के साथ काम कर रहे थे । और आपको इसे परिवर्तित करने के लिए मजबूर String.Indexesकिया जाता है जो आपके द्वारा बताए गए गंदगी की ओर जाता है।
रास्तो

इच्छुक पाठक को ExSwift github.com/pNre/ExSwift
AsTeR

42

जिस समय मैं लिख रहा हूं, कोई भी विस्तार पूरी तरह से स्विफ्ट 4.2 संगत नहीं है, इसलिए यहां एक है जो उन सभी आवश्यकताओं को शामिल करता है जो मैं सोच सकता था:

extension String {
    func substring(from: Int?, to: Int?) -> String {
        if let start = from {
            guard start < self.count else {
                return ""
            }
        }

        if let end = to {
            guard end >= 0 else {
                return ""
            }
        }

        if let start = from, let end = to {
            guard end - start >= 0 else {
                return ""
            }
        }

        let startIndex: String.Index
        if let start = from, start >= 0 {
            startIndex = self.index(self.startIndex, offsetBy: start)
        } else {
            startIndex = self.startIndex
        }

        let endIndex: String.Index
        if let end = to, end >= 0, end < self.count {
            endIndex = self.index(self.startIndex, offsetBy: end + 1)
        } else {
            endIndex = self.endIndex
        }

        return String(self[startIndex ..< endIndex])
    }

    func substring(from: Int) -> String {
        return self.substring(from: from, to: nil)
    }

    func substring(to: Int) -> String {
        return self.substring(from: nil, to: to)
    }

    func substring(from: Int?, length: Int) -> String {
        guard length > 0 else {
            return ""
        }

        let end: Int
        if let start = from, start > 0 {
            end = start + length - 1
        } else {
            end = length - 1
        }

        return self.substring(from: from, to: end)
    }

    func substring(length: Int, to: Int?) -> String {
        guard let end = to, end > 0, length > 0 else {
            return ""
        }

        let start: Int
        if let end = to, end - length > 0 {
            start = end - length + 1
        } else {
            start = 0
        }

        return self.substring(from: start, to: to)
    }
}

और फिर, आप उपयोग कर सकते हैं:

let string = "Hello,World!"

string.substring(from: 1, to: 7)आपको मिलता है: ello,Wo

string.substring(to: 7)आपको मिलता है: Hello,Wo

string.substring(from: 3)आपको मिलता है: lo,World!

string.substring(from: 1, length: 4)आपको मिलता है: ello

string.substring(length: 4, to: 7)आपको मिलता है: o,Wo

substring(from: Int?, length: Int)शून्य से शुरू होने वाले समर्थन का अद्यतन ।


यह इमोजी और विस्तारित अंगूर समूहों को कैसे संभालता है? (मुझे इसे स्वयं परीक्षण करना चाहिए लेकिन यह फिलहाल सुविधाजनक नहीं है।)
सुरगाच

2
@Suragch यह यह ठीक संभालती है: "Hello😇😍😘😎📸📀💾∝ℵℶ≹".substring(from: 4, to: 14)हमें देता है:o😇😍😘😎📸📀💾∝ℵℶ
winterized

वे सामान्य पात्रों की तरह दिखते हैं, हालांकि। इमोजी जैसे 👩👦👩 em👦👦🇨🇦🇺🇸🇲🇽 या Sup
Supuhstar

31

स्विफ्ट 2.0

सरल:

let myString = "full text container"
let substring = myString[myString.startIndex..<myString.startIndex.advancedBy(3)] // prints: ful

स्विफ्ट 3.0

let substring = myString[myString.startIndex..<myString.index(myString.startIndex, offsetBy: 3)] // prints: ful

स्विफ्ट 4.0

सबस्ट्रिंग ऑपरेशन्स स्ट्रींग के बजाय सबस्ट्रिंग प्रकार का एक उदाहरण देते हैं।

let substring = myString[myString.startIndex..<myString.index(myString.startIndex, offsetBy: 3)] // prints: ful

// Convert the result to a String for long-term storage.
let newString = String(substring)

4
Xcode 8 बीटा 6 के रूप में स्विफ्ट 3 के साथ अब संगत नहीं है, दुख की बात है
बेन मोरो

1
मेरे लिये कार्य करता है। Xcode 8, स्विफ्ट 3. मैक ओएस सिएरा पर बीटा नहीं। text[text.startIndex..<text.index(text.startIndex, offsetBy: 2)]
जोस रामिरेज़

18

एक बार जब आप सही वाक्यविन्यास पाते हैं, तो यह किसी भी उत्तर की तुलना में बहुत सरल है।

मैं दूर करना चाहता हूँ [और]

let myString = "[ABCDEFGHI]"
let startIndex = advance(myString.startIndex, 1) //advance as much as you like
let endIndex = advance(myString.endIndex, -1)
let range = startIndex..<endIndex
let myNewString = myString.substringWithRange( range )

परिणाम "ABCDEFGHI" हो जाएगा। StartIndex और endIndex का भी उपयोग किया जा सकता है

let mySubString = myString.substringFromIndex(startIndex)

और इसी तरह!

पुनश्च: जैसा कि टिप्पणी में संकेत दिया गया है, स्विफ्ट 2 में कुछ वाक्यविन्यास परिवर्तन हैं जो xcode 7 और iOS9 के साथ आता है!

कृपया इस पृष्ठ को देखें


हां, डिबगर के साथ मेरे पास वही मुद्दे थे जो कई बार सही स्ट्रिंग नहीं दिखाते हैं?
user1700737

मेरे पास एक स्ट्रिंग है जैसे / दिनांक (147410000000) /। मैं सूचकांक को निर्दिष्ट करने के बजाय मूल्य कैसे प्राप्त कर सकता हूं। मुझे rangeOfString ("(") और rangeOfString (")" का उपयोग करके मान प्राप्त करने की आवश्यकता है। परिणाम 147410000000 होना चाहिए। हो सकता है कि मैं
iPhone लड़के

यह इतना कठिन नहीं है: var str = "/ Date (147410000000) /।" var range = str.rangeOfString ("(")! endIndex .. <str.rangeOfString (")")
startIndex

4
चूँकि Xcode 7 बीटा 6 advance(myString.endIndex, -1)सिंटेक्स बदल गया हैmyString.endIndex.advancedBy(-1)
l --marc l

16

उदाहरण के लिए मेरे पूर्ण नाम में पहला नाम (पहली जगह तक) खोजें:

let name = "Joris Kluivers"

let start = name.startIndex
let end = find(name, " ")

if end {
    let firstName = name[start..end!]
} else {
    // no space found
}

startऔर यहां endप्रकार String.Indexहैं और इसका Range<String.Index>उपयोग सबस्क्रिप्ट एक्सेसर में बनाने और उपयोग करने के लिए किया जाता है (यदि मूल स्ट्रिंग में सभी में एक स्थान पाया जाता है)।

यह String.Indexएक पूर्णांक स्थिति से सीधे बनाना मुश्किल है जैसा कि उद्घाटन पोस्ट में उपयोग किया जाता है। ऐसा इसलिए है क्योंकि मेरे नाम पर प्रत्येक वर्ण बाइट्स में समान आकार का होगा। लेकिन अन्य भाषाओं में विशेष लहजे का उपयोग करने वाले वर्ण कई और बाइट्स (प्रयुक्त एन्कोडिंग के आधार पर) का उपयोग कर सकते थे। तो पूर्णांक को किस बाइट का उल्लेख करना चाहिए?

String.Indexतरीकों का उपयोग करके किसी मौजूदा से एक नया बनाना संभव है succऔर predजो एन्कोडिंग में अगले कोड बिंदु तक पहुंचने के लिए बाइट्स की सही संख्या को छोड़ देगा। हालाँकि इस मामले में अंत सूचकांक खोजने के लिए स्ट्रिंग में पहले स्थान के सूचकांक को खोजना आसान है।


16

चूंकि स्ट्रिंग NSString के लिए एक पुल प्रकार है, इसलिए "पुरानी" विधियों को काम करना चाहिए, लेकिन यह स्पष्ट नहीं है कि कैसे - जैसे, यह या तो काम नहीं करता है (मान्य सिंटैक्स प्रतीत नहीं होता है):

 let x = str.substringWithRange(NSMakeRange(0, 3))

मेरे लिए, यह आपके प्रश्न का वास्तव में दिलचस्प हिस्सा है। स्ट्रिंग है NSString को पाट, तो सबसे NSString तरीकों कर एक स्ट्रिंग पर सीधे काम करते हैं। आप उन्हें स्वतंत्र रूप से और बिना सोचे समझे उपयोग कर सकते हैं। इसलिए, उदाहरण के लिए, यह आपकी अपेक्षा के अनुरूप काम करता है:

// delete all spaces from Swift String stateName
stateName = stateName.stringByReplacingOccurrencesOfString(" ", withString:"")

लेकिन, जैसा कि अक्सर होता है, "मुझे मेरा मोजो काम मिला 'लेकिन यह सिर्फ आप पर काम नहीं करता है।" आप बस उन दुर्लभ मामलों में से एक का चयन करने के लिए हुए हैं, जहां स्विफ्ट विधि नाम से एक समानांतर पहचान मौजूद है , और इस तरह के मामले में, स्विफ्ट विधि ऑब्जेक्टिव-सी विधि की देखरेख करती है। इस प्रकार, जब आप कहते हैं str.substringWithRange, स्विफ्ट सोचता है कि आप का मतलब NSString विधि के बजाय स्विफ्ट विधि है - और फिर आपको hosed किया जाता है, क्योंकि स्विफ्ट विधि एक उम्मीद करती है Range<String.Index>, और आप नहीं जानते कि उनमें से एक कैसे बनाया जाए।

आसान तरीका यह है कि स्विफ्ट को इस तरह ओवरशेडिंग से रोकें, स्पष्ट रूप से कास्टिंग करके:

let x = (str as NSString).substringWithRange(NSMakeRange(0, 3))

ध्यान दें कि कोई भी महत्वपूर्ण अतिरिक्त कार्य यहां शामिल नहीं है। "कास्ट" का अर्थ "कन्वर्ट" नहीं है; स्ट्रिंग है प्रभावी रूप से एक NSString। हम केवल स्विफ्ट को बता रहे हैं कि इस एक कोड के उद्देश्यों के लिए इस चर को कैसे देखें

इस पूरी बात का वास्तव में अजीब हिस्सा यह है कि स्विफ्ट विधि, जो इस सभी परेशानी का कारण बनती है, अनिर्दिष्ट है। मुझे पता नहीं है कि इसे कहां परिभाषित किया गया है; यह NSString हेडर में नहीं है और यह स्विफ्ट हेडर में भी नहीं है।


हालांकि, मैं एक बग दर्ज करने का सुझाव देता हूं। Apple को "फिश या कट फेट" चाहिए - या तो हमें निर्माण करने का एक तरीका दें Range<String.Index>, या इस अनजाने तरीके को हमारे रास्ते से हटाएं।
मैट

लानत है - यह उपयोगी है। दस्तावेज़ीकरण के कहने के बावजूद, मुझे यह समझ में नहीं आया कि जब तक मैंने यह नहीं पढ़ा, तब तक क्या गलत हो रहा था। अब सॉर्ट किया गया :)
जॉन एम।

13

नए Xcode 7.0 उपयोग में

//: Playground - noun: a place where people can play

import UIKit

var name = "How do you use String.substringWithRange?"
let range = name.startIndex.advancedBy(0)..<name.startIndex.advancedBy(10)
name.substringWithRange(range)

//OUT:

यहां छवि विवरण दर्ज करें


2
.advancedBy(0) startIndex के लिए आवश्यक नहीं है।
मट्टू

12

संक्षिप्त जवाब यह है कि यह स्विफ्ट में वास्तव में कठिन है। मेरा कूबड़ यह है कि इस तरह की चीजों के लिए सुविधा के तरीकों पर Apple के लिए अभी भी काम करना बाकी है।

String.substringWithRange()एक Range<String.Index>पैरामीटर की उम्मीद कर रहा है , और जहां तक ​​मैं बता सकता हूं कि String.Indexप्रकार के लिए एक जनरेटर विधि नहीं है । आप String.Indexमूल्यों को वापस aString.startIndexऔर से प्राप्त कर सकते हैंaString.endIndex और फोन .succ()या.pred() उन पर है, लेकिन उस के पागलपन।

स्ट्रिंग वर्ग पर एक विस्तार के बारे में कैसे अच्छा पुराने Ints लेता है ?

extension String {
    subscript (r: Range<Int>) -> String {
        get {
            let subStart = advance(self.startIndex, r.startIndex, self.endIndex)
            let subEnd = advance(subStart, r.endIndex - r.startIndex, self.endIndex)
            return self.substringWithRange(Range(start: subStart, end: subEnd))
        }
    }
    func substring(from: Int) -> String {
        let end = countElements(self)
        return self[from..<end]
    }
    func substring(from: Int, length: Int) -> String {
        let end = from + length
        return self[from..<end]
    }
}

let mobyDick = "Call me Ishmael."
println(mobyDick[8...14])             // Ishmael

let dogString = "This 🐶's name is Patch."
println(dogString[5..<6])               // 🐶
println(dogString[5...5])              // 🐶
println(dogString.substring(5))        // 🐶's name is Patch.
println(dogString.substring(5, length: 1))   // 🐶

अपडेट करें: स्विफ्ट बीटा 4 नीचे के मुद्दों को हल करता है!

जैसा कि यह [बीटा 3 और पूर्व में] खड़ा है, यहां तक ​​कि स्विफ्ट-देशी स्ट्रिंग्स में यूनिकोड पात्रों को संभालने के साथ कुछ मुद्दे हैं। ऊपर दिया गया कुत्ता आइकन काम करता है, लेकिन निम्नलिखित नहीं है:

let harderString = "1:1️⃣"
for character in harderString {
    println(character)
}

आउटपुट:

1
:
1
️
⃣

1
यह अजीब है, कोर स्विफ्ट कक्षाएं बस बहुत सारे बुनियादी कार्यों की कमी लगती हैं। मुझे नहीं लगता कि Apple चाहता है कि हम साधारण कार्यों को करने के लिए लगातार फ़ाउंडेशन क्लासेस का संदर्भ लें।
bluedevil2k

1
पूरी तरह से। ध्यान रखें कि स्विफ्ट मूल रूप से अंधेरे में विकसित हुई थी, और हर किसी की "सरल कार्यों" की एक अलग परिभाषा है - मुझे यकीन है कि हम इन मुद्दों पर कुछ त्वरित पुनरावृत्ति देखते हैं।
नैट कुक

@ JanX2 - धन्यवाद, आप पूरी तरह से सही हैं। निर्बाध साथ ब्रिजिंग NSStringमुझे लगता है कि मैं केवल स्विफ्ट देशी उपयोग कर रहा था बनाया Stringतरीकों, के बाद से मैं किसी भी उपयोग नहीं किया गया था myString as NSStringकॉल।
नैट कुक

स्विफ्ट-देशी स्ट्रिंग हैंडलिंग में अभी कुछ यूनिकोड बग हैं, भी: अंत में मेरा नोट देखें।
नैट कुक

@NateCook क्या आप उस समस्या के लिए रडार दर्ज कर सकते हैं?
JanX2

11

सुधार के लिए आप इस एक्सटेंशन का उपयोग कर सकते हैं substringWithRange

स्विफ्ट 2.3

extension String
{   
    func substringWithRange(start: Int, end: Int) -> String
    {
        if (start < 0 || start > self.characters.count)
        {
            print("start index \(start) out of bounds")
            return ""
        }
        else if end < 0 || end > self.characters.count
        {
            print("end index \(end) out of bounds")
            return ""
        }
        let range = Range(start: self.startIndex.advancedBy(start), end: self.startIndex.advancedBy(end))
        return self.substringWithRange(range)
    }

    func substringWithRange(start: Int, location: Int) -> String
    {
        if (start < 0 || start > self.characters.count)
        {
            print("start index \(start) out of bounds")
            return ""
        }
        else if location < 0 || start + location > self.characters.count
        {
            print("end index \(start + location) out of bounds")
            return ""
        }
        let range = Range(start: self.startIndex.advancedBy(start), end: self.startIndex.advancedBy(start + location))
        return self.substringWithRange(range)
    }
}

स्विफ्ट 3

extension String
{
    func substring(start: Int, end: Int) -> String
    {
        if (start < 0 || start > self.characters.count)
        {
            print("start index \(start) out of bounds")
            return ""
        }
        else if end < 0 || end > self.characters.count
        {
            print("end index \(end) out of bounds")
            return ""
        }
        let startIndex = self.characters.index(self.startIndex, offsetBy: start)
        let endIndex = self.characters.index(self.startIndex, offsetBy: end)
        let range = startIndex..<endIndex

        return self.substring(with: range)
    }

    func substring(start: Int, location: Int) -> String
    {
        if (start < 0 || start > self.characters.count)
        {
            print("start index \(start) out of bounds")
            return ""
        }
        else if location < 0 || start + location > self.characters.count
        {
            print("end index \(start + location) out of bounds")
            return ""
        }
        let startIndex = self.characters.index(self.startIndex, offsetBy: start)
        let endIndex = self.characters.index(self.startIndex, offsetBy: start + location)
        let range = startIndex..<endIndex

        return self.substring(with: range)
    }
}

उपयोग:

let str = "Hello, playground"

let substring1 = str.substringWithRange(0, end: 5) //Hello
let substring2 = str.substringWithRange(7, location: 10) //playground

7

स्विफ्ट 2.0 में प्रतिस्थापन के लिए नमूना कोड

(i) इंडेक्स शुरू करने से उपजाऊ

इनपुट: -

var str = "Swift is very powerful language!"
print(str)

str = str.substringToIndex(str.startIndex.advancedBy(5))
print(str)

आउटपुट: -

Swift is very powerful language!
Swift

(ii) विशेष सूचकांक से पदार्थ

इनपुट: -

var str = "Swift is very powerful language!"
print(str)

str = str.substringFromIndex(str.startIndex.advancedBy(6)).substringToIndex(str.startIndex.advancedBy(2))
print(str)

आउटपुट: -

Swift is very powerful language!
is

मुझे आशा है कि यह आपकी मदद करेगा!


7

छोटे कोड के साथ आसान समाधान।

एक विस्तार करें जिसमें मूल सबस्ट्रिंग शामिल है जो लगभग सभी अन्य भाषाओं में हैं:

extension String {
    func subString(start: Int, end: Int) -> String {
        let startIndex = self.index(self.startIndex, offsetBy: start)
        let endIndex = self.index(startIndex, offsetBy: end)

        let finalString = self.substring(from: startIndex)
        return finalString.substring(to: endIndex)
    }
}

इसके साथ ही कॉल करें

someString.subString(start: 0, end: 6)

1
'अंत' पैरामीटर का मतलब वास्तव में यहां लंबाई है, इसलिए मुझे लगता है कि इसका नाम बदल दिया जाना चाहिए।
जोवन जोवानोवस्की

मुझे लगता है कि लंबाई का उपयोग करना भ्रामक है। यह वास्तव में 'अंत' है जहाँ आप सबस्ट्रिंग होना चाहते हैं, उप-परिणाम की वास्तविक लंबाई नहीं।
ओलिवर डिक्सन

6

यह मेरे खेल के मैदान में काम करता है :)

String(seq: Array(str)[2...4])

वास्तव में यह कॉल करने की तुलना में अधिक कुशल हैadvance
एरिक एग्नर

2
यह मेरे Xcode 7 (स्विफ्ट 2) खेल के मैदान में काम नहीं कर रहा है, लेकिन यह करता है ... 'var str = "Hello, खेल का मैदान"' String (Array (str.characters) [7]) // "p" String (Array ( str.characters) [7 ... 10]) // "प्ले" स्ट्रिंग (Array (str.characters) [7 .. <10]) // "पीएलए"
विंस ओ'सुल्लिवन

6

Xcode के लिए अपडेट किया गया है। स्ट्रिंग एक्सटेंशन जोड़ता है:

उपयोग:

var chuck: String = "Hello Chuck Norris"
chuck[6...11] // => Chuck

कार्यान्वयन:

extension String {

    /**
     Subscript to allow for quick String substrings ["Hello"][0...1] = "He"
     */
    subscript (r: Range<Int>) -> String {
        get {
            let start = self.startIndex.advancedBy(r.startIndex)
            let end = self.startIndex.advancedBy(r.endIndex - 1)
            return self.substringWithRange(start..<end)
        }
    }

}

4

खेल के मैदान में यह कोशिश करो

var str:String = "Hello, playground"

let range = Range(start:advance(str.startIndex,1), end: advance(str.startIndex,8))

यह आपको देगा "एलो, पी" देगा

हालाँकि, जहाँ यह वास्तव में दिलचस्प है कि यदि आप खेल के मैदान में स्ट्रिंग से अंतिम इंडेक्स को बड़ा बनाते हैं तो यह आपके द्वारा परिभाषित किए गए किसी भी तार को दिखाएगा: ओ

रेंज () एक जेनेरिक फ़ंक्शन प्रतीत होता है, ताकि उसे यह पता होना चाहिए कि वह किस प्रकार से काम कर रहा है।

आपको इसे खेल के मैदानों में अपनी रूचि के अनुसार वास्तविक स्ट्रिंग भी देनी होगी क्योंकि ऐसा लगता है कि यह क्रम में सभी स्टिंग्स को एक के बाद एक उनके चर नाम के साथ पकड़ता है।

इसलिए

var str:String = "Hello, playground"

var str2:String = "I'm the next string"

let range = Range(start:advance(str.startIndex,1), end: advance(str.startIndex,49))

देता है "एलो, playgroundstrI'm अगले stringstr2"

भले ही str2 को लेट से परिभाषित किया गया हो

:)


मैं मानता हूं कि यह वस्तुनिष्ठ-सी की तुलना में क्रिया है, हालांकि यह सब एक पंक्ति पर फिट बैठता है जो एक बोनस है।
पीटर रॉबर्ट्स

अच्छी तरह से अभी भी एक लाइन गायब है जो वास्तव में आपके द्वारा गणना की गई श्रेणी के प्रतिस्थापन को प्रिंट करती है। मुझे कुछ अन्य समाधान पसंद हैं जो आपके तर्क का उपयोग करते हुए स्ट्रिंग क्लास एक्सटेंशन बनाते हैं, लेकिन एक एक्सटेंशन में। अंतत: वह समाधान है जिसके साथ मैं गया था।
रोडरिक कैम्पबेल

उन्होंने बग को तय किया है जहां आप स्ट्रिंग के अंत से परे जा सकते हैं। अब आप केवल str.endIndex
पीटर रॉबर्ट्स

4

रोब नेपियर ने पहले ही सबस्क्रिप्ट का उपयोग करके एक शानदार जवाब दिया था। लेकिन मुझे इसमें एक खामी महसूस हुई क्योंकि बाध्य परिस्थितियों से बाहर आने के लिए कोई जांच नहीं है। इससे दुर्घटना हो सकती है। इसलिए मैंने विस्तार को संशोधित किया और यहां यह है

extension String {
    subscript (r: Range<Int>) -> String? { //Optional String as return value
        get {
            let stringCount = self.characters.count as Int
            //Check for out of boundary condition
            if (stringCount < r.endIndex) || (stringCount < r.startIndex){
                return nil
            }
            let startIndex = self.startIndex.advancedBy(r.startIndex)

            let endIndex = self.startIndex.advancedBy(r.endIndex - r.startIndex)

            return self[Range(start: startIndex, end: endIndex)]
        }
    }
}

नीचे उत्पादन

var str2 = "Hello, World"

var str3 = str2[0...5]
//Hello,
var str4 = str2[0..<5]
//Hello
var str5 = str2[0..<15]
//nil

तो मैं हमेशा सुझाव देता हूं कि अगर आने दिया जाए

if let string = str[0...5]
{
    //Manipulate your string safely
}

आपको वहां एक बग मिल गया है - एंडइंडेक्स को स्टार्ट इंडेक्स होना चाहिए जो एंडएंडेक्स द्वारा उन्नत हो, न कि सूचकांकों के बीच की दूरी।
अवध बेन डोव

3

में Swift3

पूर्व के लिए: एक चर "ड्यूक जेम्स थॉमस", हमें "जेम्स" प्राप्त करने की आवश्यकता है।

let name = "Duke James Thomas"
let range: Range<String.Index> = name.range(of:"James")!
let lastrange: Range<String.Index> = img.range(of:"Thomas")!
var middlename = name[range.lowerBound..<lstrange.lowerBound]
print (middlename)

2

रोब नेपियर का एक पृष्ठ लेते हुए, मैंने ये सामान्य स्ट्रिंग एक्सटेंशन विकसित किए , जिनमें से दो हैं:

subscript (r: Range<Int>) -> String
{
    get {
        let startIndex = advance(self.startIndex, r.startIndex)
        let endIndex = advance(self.startIndex, r.endIndex - 1)

        return self[Range(start: startIndex, end: endIndex)]
    }
}

func subString(startIndex: Int, length: Int) -> String
{
    var start = advance(self.startIndex, startIndex)
    var end = advance(self.startIndex, startIndex + length)
    return self.substringWithRange(Range<String.Index>(start: start, end: end))
}

उपयोग:

"Awesome"[3...7] //"some"
"Awesome".subString(3, length: 4) //"some"

आप धन्यवाद टाइप करने के लिए धन्यवाद के Rangeबजाय उपयोग कर सकते हैं Range<String.Index>
दान रोसेनस्टार्क

2

यह है कि आपको स्ट्रिंग से श्रेणी कैसे मिलती है:

var str = "Hello, playground"

let startIndex = advance(str.startIndex, 1)
let endIndex = advance(startIndex, 8)
let range = startIndex..<endIndex
let substr = str[range] //"ello, pl"

मुख्य बिंदु यह है कि आप पूर्णांक के बजाय String.Index (यह वही अग्रिम प्रतिफल है) के मानों की एक सीमा से गुजर रहे हैं।

यह आवश्यक क्यों है, इसका कारण यह है कि स्विफ्ट में तार बेतरतीब ढंग से नहीं चलते हैं (मूल रूप से यूनिकोड वर्णों की चर लंबाई के कारण)। आप भी नहीं कर सकतेstr[1] । String.Index उनकी आंतरिक संरचना के साथ काम करने के लिए डिज़ाइन किया गया है।

आप एक सबस्क्रिप्ट के साथ एक एक्सटेंशन बना सकते हैं, हालांकि, यह आपके लिए है, इसलिए आप केवल पूर्णांकों की एक सीमा पास कर सकते हैं (उदाहरण के लिए रोब नेपियर का उत्तर देखें )।


2

मैंने कुछ पाइथोनिक के साथ आने की कोशिश की।

यहां सभी सदस्यताएं महान हैं, लेकिन जिस समय मुझे वास्तव में कुछ सरल चाहिए, आमतौर पर जब मैं पीछे से गिनती करना चाहता हूं, जैसे string.endIndex.advancedBy(-1)

यह nilमूल्यों का समर्थन करता है, दोनों शुरू और अंत सूचकांक के लिए, जहां nilशुरुआत के लिए 0 पर सूचकांक का मतलब होगा, string.characters.countअंत के लिए।

extension String {
    var subString: (Int?) -> (Int?) -> String {
        return { (start) in
            { (end) in
                let startIndex = start ?? 0 < 0 ? self.endIndex.advancedBy(start!) : self.startIndex.advancedBy(start ?? 0)
                let endIndex = end ?? self.characters.count < 0 ? self.endIndex.advancedBy(end!) : self.startIndex.advancedBy(end ?? self.characters.count)

                return startIndex > endIndex ? "" : self.substringWithRange(startIndex ..< endIndex)
            }
        }
    }
}

let dog = "Dog‼🐶"
print(dog.subString(nil)(-1)) // Dog!!

संपादित करें

एक और अधिक सुंदर समाधान:

public extension String {
    struct Substring {
        var start: Int?
        var string: String

        public subscript(end: Int?) -> String {
            let startIndex = start ?? 0 < 0 ? string.endIndex.advancedBy(start!) : string.startIndex.advancedBy(start ?? 0)
            let endIndex = end ?? string.characters.count < 0 ? string.endIndex.advancedBy(end!) : string.startIndex.advancedBy(end ?? string.characters.count)

            return startIndex > endIndex ? "" : string.substringWithRange(startIndex ..< endIndex)
        }
    }

    public subscript(start: Int?) -> Substring {
        return Substring(start: start, string: self)
    }
}

let dog = "Dog‼🐶"
print(dog[nil][-1]) // Dog!!

1

पहले रेंज बनाएं, फिर सबस्ट्रिंग। आप fromIndex..<toIndexसिंटैक्स का उपयोग कर सकते हैं जैसे:

let range = fullString.startIndex..<fullString.startIndex.advancedBy(15) // 15 first characters of the string
let substring = fullString.substringWithRange(range)

1

यहाँ वीडियो-Id केवल .ie (6oL687G0Iso) को पूरे URL से तेज़ी से प्राप्त करने के लिए एक उदाहरण है

let str = "https://www.youtube.com/watch?v=6oL687G0Iso&list=PLKmzL8Ib1gsT-5LN3V2h2H14wyBZTyvVL&index=2"
var arrSaprate = str.componentsSeparatedByString("v=")
let start = arrSaprate[1]
let rangeOfID = Range(start: start.startIndex,end:start.startIndex.advancedBy(11))
let substring = start[rangeOfID]
print(substring)

1
let startIndex = text.startIndex
var range = startIndex.advancedBy(1) ..< text.endIndex.advancedBy(-4)
let substring = text.substringWithRange(range)

पूर्ण नमूना आप यहाँ देख सकते हैं


0

http://www.learnswiftonline.com/reference-guides/string-reference-guide-for-swift/ दर्शाता है कि यह अच्छी तरह से काम करता है:

var str = "abcd"
str = str.substringToIndex(1)

3
खेल का मैदान निष्पादन में विफल रहा: त्रुटि: <EXPR>: 23: 5: त्रुटि: टाइप करें 'String.Index' प्रोटोकॉल के अनुरूप नहीं है 'IntegerLiteralConvertible' str = str.substringToIndex (1 ^)
बेन वर्टेन्घेन

0

खैर, मेरे पास एक ही मुद्दा था और "BridgeToObjectiveC ()" फ़ंक्शन के साथ हल किया गया था:

var helloworld = "Hello World!"
var world = helloworld.bridgeToObjectiveC().substringWithRange(NSMakeRange(6,6))
println("\(world)") // should print World!

कृपया ध्यान दें कि NSMakeRange के साथ संयोजन में substringWithRange सूचकांक 6 (चरित्र "डब्ल्यू") पर शुरू होने वाले स्ट्रिंग का हिस्सा लेते हैं और सूचकांक 6 + 6 पदों पर आगे (चरित्र "!") को समाप्त करते हैं।

चीयर्स।


मुझे इससे नफरत है, लेकिन यह केवल एक चीज है जो मेरे लिए बीटा 4 में काम कर रही है।
रोड्रिक कैम्पबेल

0

आप स्विफ्ट स्ट्रिंग एक्सटेंशन में लिखी गई किसी भी सब्स्क्राइब्ड विधियों का उपयोग कर सकते हैं मैंने https://bit.ly/JString लिखा है ।

var string = "hello"
var sub = string.substringFrom(3) // or string[3...5]
println(sub)// "lo"

0

यदि आपके पास एक है NSRange, तो NSStringमूल काम करने के लिए ब्रिजिंग । उदाहरण के लिए, मैं कुछ काम कर रहा था UITextFieldDelegateऔर मैं जल्दी से नए स्ट्रिंग मान की गणना करना चाहता था जब उसने पूछा कि क्या इसे रेंज को बदलना चाहिए।

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
    let newString = (textField.text as NSString).stringByReplacingCharactersInRange(range, withString: string)
    println("Got new string: ", newString)
}


0

यदि आप प्रदर्शन के बारे में परवाह नहीं करते हैं ... यह स्विफ्ट 4 में संभवतः सबसे संक्षिप्त समाधान है

extension String {
    subscript(range: CountableClosedRange<Int>) -> String {
        return enumerated().filter{$0.offset >= range.first! && $0.offset < range.last!}
            .reduce(""){$0 + String($1.element)}
    }
}

यह आपको ऐसा कुछ करने में सक्षम बनाता है:

let myStr = "abcd"
myStr[0..<2] // produces "ab"
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.