আপনি কীভাবে স্ট্রিং.সুবস্ট্রিং উইথরেঞ্জ ব্যবহার করবেন? (বা, স্যুইফটে রেঞ্জগুলি কীভাবে কাজ করে?)


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))

থটস?


আপনি যখন শেষের উদাহরণটি কাজ করেন না তখন আপনার অর্থ কী? এটি কি ত্রুটি সৃষ্টি করে বা একটি অপ্রত্যাশিত মান ফেরত দেয়?
67cherries

দয়া করে প্রতারিত rdar: // 17158813 অনুরোধ সাবস্ক্রিপ্ট স্বরলিপি openradar.appspot.com/radar?id=6373877630369792
রব নেপিয়ের

উত্তর:


259

আপনি সাবস্ট্রিং উইথ্রেঞ্জ পদ্ধতিটি ব্যবহার করতে পারেন। এটি স্ট্রিং.আইডেক্স সূচনা এবং শেষ করে।

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"

আপনি এখনও এনএসআরঞ্জের সাথে এনএসএসস্ট্রিং পদ্ধতিটি ব্যবহার করতে পারেন তবে আপনাকে অবশ্যই এনএসএস স্ট্রিং ব্যবহার করছেন তা নিশ্চিত করতে হবে:

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

দ্রষ্টব্য: জানেক্স 2 যেমন উল্লেখ করেছে, এই দ্বিতীয় পদ্ধতিটি ইউনিকোড স্ট্রিং সহ নিরাপদ নয়।


5
হ্যাঁ। আপাতত আমি যখন প্রয়োজন তখন এনএসএসস্ট্রিং ব্রিজিং চালিয়ে যাব। দেখে মনে হচ্ছে সুইফ্টের স্ট্রিংটি এখনও অসম্পূর্ণ
কনার

14
এটি নিরাপদ নয়! আপনি ধরে নিচ্ছেন যে স্ট্রিং এবং এনএসএস স্ট্রিংয়ের সূচিগুলি বিনিময়যোগ্য। ব্যাপার সেটা না. স্ট্রিংয়ের সূচিগুলি ইউনিকোড কোড পয়েন্টগুলি উল্লেখ করে যখন এনএসএস স্ট্রিংয়ের সূচিগুলি ইউটিএফ -16 কোড ইউনিটকে বোঝায়! ইমোজি দিয়ে চেষ্টা করে দেখুন।
জানুয়ার 2

3
দয়া করে মনে রাখবেন যে স্ট্রিংয়ের সূচিগুলি ইউনিকোড কোড পয়েন্টগুলিকে আর উল্লেখ করে না। এগুলি ব্যবহারকারী-অনুধাবিত অক্ষরগুলিকে রেফারেন্স হিসাবে ভাবেন।
জানু 2

2
তাহলে এখানে সঠিক উত্তর কি? কল করার advanceঅর্থ সম্ভবত একটি দীর্ঘতর স্ট্রিংয়ের মাধ্যমে পুরো পথটি পুনরাবৃত্তি করতে হবে। তবে এনএসআরঞ্জ গঠন করা এবং এনএসএসস্ট্রিং স্পষ্টভাবে ব্যবহার করা বিপজ্জনক? কি বাকী আছে?
ম্যাট

1
ধন্যবাদ, এম 8 সুইফটে এই রূপান্তরটি কেবল অবজেক্টিভ-সি করার 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 টি স্ট্রিং অপারেশন স্ট্রিংয়ের পরিবর্তে সাবস্ট্রিং প্রকারের একটি উদাহরণ দেয় return দীর্ঘমেয়াদী স্টোরেজের জন্য ফলাফলটিকে স্ট্রিংয়ে রূপান্তর করা দরকার। newString = স্ট্রিং (সাবস্ট্রিং)
phnmnn

43

দ্রষ্টব্য: @ মায়ারস্পিডসউফট এই পদ্ধতির ট্রেড-অফ সম্পর্কে বিশেষত লুকানো কর্মক্ষমতা প্রভাব সম্পর্কে কিছুটা অন্তর্দৃষ্টিপূর্ণ পয়েন্ট তৈরি করেছে। স্ট্রিংগুলি সাধারণ জন্তু নয়, এবং কোনও নির্দিষ্ট সূচকে উঠতে 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"

(এটি অবশ্যই ভাষার অংশ হওয়া উচিত Please অনুগ্রহ করে রাদার: // 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
পারফরম্যান্স কারণে আমাদের যথাসম্ভব পূর্ণসংখ্য সূচকগুলির পরিবর্তে স্ট্রিং.ইনডেক্সের সাথে কাজ করা উচিত। একটি পূর্ণসংখ্যা সূচক থেকে প্রতিটি স্ট্রিংয়ে রূপান্তরকরণের জন্য nd সূচকটি স্ট্রিংটি অনুসন্ধান করার জন্য প্রয়োজন।
জানুয়ার 2

11
@ অ্যান্ড্রুডান এটি অকাল অপটিমাইজেশন নয়। একটি পূর্ণসংখ্যা সূচক থেকে প্রতিটি স্ট্রিংয়ে রূপান্তর হয় I সূচকটি ও (এন) হয়, ও (1) নয়! জন্য দয়া করে মন্তব্য পড়তে advance<T>(…)মধ্যে Swiftনামস্থান।
জানুস 2

1
স্ট্রিং বাস্তবায়ন পুরো ব্যবহার করে করা হয় String.Index। এই ক্ষেত্রে এটি এতটা অপ্টিমাইজেশন নয় যতটা এটি সবকিছু সোজা করে রাখছে। ইনট এবং স্ট্রিংয়ের মধ্যে জাগল করা nd ইন্ডেক্সের পিছনে এবং সর্বত্র সর্বত্র গোলমাল সৃষ্টি হবে।
চক্রত

@ চাচারত কেবলমাত্র যদি আপনার সূচীগুলি ব্যবহার করতে হয় তবে ইতিমধ্যে এটি ইতিমধ্যে পূর্ণসংখ্যার ( String.Indexএস না হওয়ার পরিবর্তে ) হয় না। আপনি যে সমস্ত স্ট্রিং হ্যান্ডলিং পদ্ধতিগুলি Intএস এর সাথে কাজ করছিলেন তা কেবল ইচ্ছা করতে পারেন । এবং আপনি এটিকে রূপান্তর করতে বাধ্য হন String.Indexesযা আপনার উল্লিখিত গোলমালের দিকে নিয়ে যায়।
রাস্তো

আগ্রহী পাঠক ExSwift কটাক্ষপাত দিতে হবে github.com/pNre/ExSwift
Aster

42

আমি যে সময় লিখছি, কোনও এক্সটেনশন পুরোপুরি সুইফট ৪.২ সামঞ্জস্যপূর্ণ নয়, সুতরাং এখানে এমন একটি যা আমি ভাবতে পারি এমন সমস্ত প্রয়োজনীয়তা কভার করে:

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
@ সুরগাচ এটি পরিচালনা করে ঠিক আছে: "Hello😇😍😘😎📸📀💾∝ℵℶ≹".substring(from: 4, to: 14)আমাদের দেয়:o😇😍😘😎📸📀💾∝ℵℶ
শীতকালীন করা হয়েছে

যদিও এগুলি দেখতে সাধারণ চরিত্রগুলির মতো। :‍👩‍👧‍👦 বা 🇨🇦🇺🇸🇲🇽
সুপুস্তর

31

সুইফট ২.০

সহজ:

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

SWIFT 3.0

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

SWIFT 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
আমার জন্য কাজ কর. এক্সকোড 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" হবে স্টার্টইনডেক্স এবং এন্ডআইডেক্সও ব্যবহার করা যেতে পারে

let mySubString = myString.substringFromIndex(startIndex)

এবং তাই!

পিএস: মন্তব্যগুলিতে ইঙ্গিত হিসাবে, সুইফট 2 এ কিছু সিনট্যাক্স পরিবর্তন রয়েছে যা এক্সকোড 7 এবং আইওএস 9 এর সাথে আসে!

এই পৃষ্ঠাটি দেখুন দয়া করে


হ্যাঁ, আমার একই সমস্যা ছিল ডিবাগারটি বেশ কয়েকবার সঠিক স্ট্রিংটি প্রদর্শন না করে?
ব্যবহারকারী 1700737

আমার কাছে এই / তারিখের (147410000000) / স্ট্রিং রয়েছে। আমি কীভাবে সূচকটি উল্লেখ করার পরিবর্তে মান পেতে পারি। রেঞ্জঅফস্ট্রিং ("(") এবং রেঞ্জঅফস্ট্রিং (")") ব্যবহার করে আমার মানটি পাওয়া দরকার। ফলাফলের 147410000000. নিড়ানি আমি যে পেতে পারেন হওয়া উচিত
আইফোন গাই

এটি এতটা কঠিন নয়: var str = "/ তারিখ (147410000000) /"। var পরিসীমা = str.rangeOfString ("(")! endIndex .. <str.rangeOfString (")") !. startIndex myNewString = str.substringWithRange (পরিসর)
ব্যবহারকারী 1700737

4
advance(myString.endIndex, -1)myString.endIndex.advancedBy(-1)
এক্সকোড

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

স্ট্রিং যেহেতু এনএসএসস্ট্রিংয়ের জন্য একটি সেতুর ধরণ, তাই "পুরাতন" পদ্ধতিগুলি ব্যবহার করা উচিত, তবে কীভাবে তা বোঝা যায় না - উদাহরণস্বরূপ, এটি কোনওভাবে কাজ করে না (বৈধ বাক্য গঠন হিসাবে উপস্থিত হয় না):

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

আমার কাছে, এটি আপনার প্রশ্নের সত্যই আকর্ষণীয় অংশ। স্ট্রিং হয় NSString করার সেতু নির্মাণ, তাই সবচেয়ে NSString পদ্ধতি কি স্ট্রিং সরাসরি হবে। আপনি এগুলি অবাধে এবং চিন্তাভাবনা না করে ব্যবহার করতে পারেন। সুতরাং, উদাহরণস্বরূপ, এটি আপনার প্রত্যাশার মতোই কাজ করে:

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

তবে, প্রায়শই ঘটে যায়, "আমি আমার মোজো ওয়ার্কিন পেয়েছি" তবে এটি কেবল আপনার কাজ করে না। আপনি সবেমাত্র এমন একটি বিরল ক্ষেত্রে বাছাই করতে পেরেছিলেন যেখানে সমান্তরালভাবে স্বীকৃত সুইফট পদ্ধতিটি বিদ্যমান এবং এর মতো ক্ষেত্রে সুইফট পদ্ধতিটি উদ্দেশ্য-সি পদ্ধতির ওভারশ্যাড করে। সুতরাং, আপনি যখন বলছেন str.substringWithRange, সুইফ্ট মনে করেন আপনি এনএসএসটিং পদ্ধতির পরিবর্তে সুইফট পদ্ধতিটি বোঝাচ্ছেন - এবং তারপরে আপনি হোসড হন, কারণ সুইফ্ট পদ্ধতিটি একটি আশা করে Range<String.Index>, এবং কীভাবে এটি তৈরি করতে হয় তা আপনি জানেন না।

সহজ উপায় হ'ল সুইফটকে এভাবে ওভারশেডিং থেকে বিরত রাখা, স্পষ্টভাবে কাস্টিং দ্বারা:

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

মনে রাখবেন যে এখানে কোনও উল্লেখযোগ্য অতিরিক্ত কাজ জড়িত নেই। "কাস্ট" এর অর্থ "রূপান্তর" নয়; স্ট্রিং হয় কার্যকরভাবে একটি NSString। আমরা কেবল সুইফটকে বলছি কীভাবে এই এক লাইনের কোডের উদ্দেশ্যে এই পরিবর্তনশীলটির দিকে নজর দেওয়া যায়।

এই পুরোপুরিটির সত্যই অদ্ভুত অংশটি হ'ল সুইফ্ট পদ্ধতি যা এই সমস্ত সমস্যার কারণ হয়ে থাকে, তা অনির্ধারিত। এটি কোথায় সংজ্ঞায়িত হয়েছে তা আমার কোনও ধারণা নেই; এটি এনএসএসস্ট্রিং শিরোনামে নেই এবং এটি সুইফ্ট শিরোনামেও নেই।


তবে আমি একটি বাগ ফাইল করার পরামর্শ দিচ্ছি। অ্যাপল "মাছ বা টোপ কাটা" উচিত - হয় আমাদের একটি নির্মাণের জন্য একটি উপায় দিন Range<String.Index>, বা এই অনাবন্ধিত পদ্ধতিটি আমাদের পথ থেকে সরিয়ে দিন।
ম্যাট

জঘন্য - এটি দরকারী। ডকুমেন্টেশন যা বলেছে তা সত্ত্বেও, আমি এটি না পড়া পর্যন্ত বুঝতে পারিনি কী ভুল হচ্ছে। এখন সাজানো হয়েছে :)
জন এম

13

নতুন এক্সকোডে 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) স্টার্ট ইন্ডেক্সের জন্য প্রয়োজনীয় নয়।
Mat0

12

সংক্ষিপ্ত উত্তরটি হ'ল এটি এখনই সুইফ্টে সত্যই শক্ত। আমার কুণ্ডলীটি হ'ল অ্যাপলের পক্ষে এই জাতীয় জিনিসগুলির সুবিধার্থে করার জন্য এখনও অনেক কিছু কাজ বাকি আছে।

String.substringWithRange()একটি Range<String.Index>প্যারামিটারের প্রত্যাশা করছে , এবং যতদূর আমি বলতে পারি String.Indexপ্রকারের জন্য কোনও জেনারেটর পদ্ধতি নেই । আপনি পেতে পারেন String.Indexমান থেকে ব্যাক aString.startIndexএবং aString.endIndexএবং কল .succ()বা.pred() তাদের উপর, কিন্তু যে এর পাগলামি।

স্ট্রিং ক্লাসে এমন একটি এক্সটেনশান সম্পর্কে কী বলা যায় যা পুরানো ভাল লাগে Int?

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
এটি অদ্ভুত, মূল সুইফ্ট ক্লাসগুলির মনে হয় কেবলমাত্র অনেকগুলি মৌলিক ফাংশনের অভাব রয়েছে। আমি ভাবতে পারি না যে অ্যাপল আমাদের ফাউন্ডেশন ক্লাসের নিয়মিত সাধারণ কাজগুলি সম্পাদন করতে চায়।
bluedevil2k

1
পুরোটাই। মনে রাখবেন যে সুইফটটি মূলত অন্ধকারে বিকশিত হয়েছিল এবং প্রত্যেকেরই "সাধারণ কাজগুলি" এর আলাদা সংজ্ঞা রয়েছে - আমি বাজি ধরছি আমরা এই বিষয়গুলিতে কিছু দ্রুত পুনরাবৃত্তি দেখতে পাই।
নেট কুক

@ জ্যানএক্স 2 - ধন্যবাদ, আপনি পুরোপুরি ঠিক বলেছেন। সীমাহীন সেতুটি NSStringআমাকে মনে করেছিল যে আমি কেবল সুইফট-নেটিভ Stringপদ্ধতি ব্যবহার করছি, যেহেতু আমি কোনও myString as NSStringকল ব্যবহার করছিলাম না ।
নেট কুক

এখনই সুইফট-নেটিভ স্ট্রিং হ্যান্ডলিংয়ে কিছু ইউনিকোড বাগ রয়েছে: আমার নোটটি শেষে দেখুন।
নেট কুক

@ নেটকুক আপনি কি এই সমস্যার জন্য একটি রাডার ফাইল করতে পারেন?
জান এক্স 2

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

কীভাবে সুইফট ২.০ এ সাবস্ট্রিং পাবেন তার নমুনা কোড

(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
এটি আমার এক্সকোড 7 (সুইফট 2) খেলার মাঠে কাজ করছে না, তবে এটি করে ... 'var str = "হ্যালো, খেলার মাঠ" "স্ট্রিং (অ্যারে (str.characters) [7]) //" পি "স্ট্রিং (অ্যারে ( স্ট্র্যাচ্যাক্টরস) [7 ... 10]) // "স্ট্রিং খেলুন (অ্যারে (টিআরএফ্যাক্রেটারস) [7 .. <10]) //" পিএলএ "
ভিন্স ও'সুলিভান

6

এক্সকোড for এর জন্য আপডেট হয়েছে St স্ট্রিং এক্সটেনশন যুক্ত করে:

ব্যবহার করুন:

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))

এটি আপনাকে "ইলো, পি" দেবে

তবে যেখানে এটি সত্যিই আকর্ষণীয় হবে তা হ'ল আপনি যদি খেলার মাঠের স্ট্রিংয়ের চেয়ে শেষ সূচকটি আরও বড় করেন তবে এটি স্ট্রিংয়ের পরে সংজ্ঞায়িত যে কোনও স্ট্রিং প্রদর্শন করবে: o

ব্যাপ্তি () একটি জেনেরিক ফাংশন হিসাবে উপস্থিত হয় যাতে এটি কী ধরণের আচরণ করছে তা জানতে হবে।

খেলার মাঠগুলিতে আপনার আগ্রহটি আপনাকে এটিকে প্রকৃত স্ট্রিংও দিতে হবে কারণ এটি মনে হয় যে সমস্ত স্টিংগুলি একের পর এক ক্রমগুলিতে তাদের ভেরিয়েবল নাম সহ একের পর এক ধরে রেখেছে।

সুতরাং

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))

দেয় "Ello, 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"

মূল বক্তব্যটি হ'ল আপনি পূর্ণসংখ্যার পরিবর্তে স্ট্রিং.ইনডেক্স (এটাই অগ্রিম ফেরত দেয়) প্রকারের মানগুলির একটি পরিসর অতিক্রম করছেন।

এটি প্রয়োজনীয় হওয়ার কারণটি হ'ল সুইফ্টের স্ট্রিংগুলিতে এলোমেলো অ্যাক্সেস নেই (মূলত ইউনিকোডের অক্ষরগুলির পরিবর্তনশীল দৈর্ঘ্যের কারণে)। আপনিও করতে পারবেন নাstr[1] । স্ট্রিং.ইনডেক্স তাদের অভ্যন্তরীণ কাঠামোর সাথে কাজ করার জন্য ডিজাইন করা হয়েছে।

আপনি যদিও সাবস্ক্রিপ্টের সাহায্যে একটি এক্সটেনশন তৈরি করতে পারেন, এটি আপনার জন্য এটি করে, যাতে আপনি কেবলমাত্র একটি পূর্ণসংখ্যার পাস করতে পারেন (যেমন রব নেপিয়ারের উত্তর দেখুন )।


2

আমি পাইথোনিক কিছু নিয়ে আসার চেষ্টা করেছি।

এখানে সমস্ত সাবস্ক্রিপ্টগুলি দুর্দান্ত, তবে আমার যখন সাধারণ কিছু দরকার তখন সাধারণত যখন আমি পিছন থেকে গণনা করতে চাই want 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

শুধুমাত্র ভিডিও-আইডি পাওয়ার জন্য এখানে একটি উদাহরণ রয়েছে। দ্রুত ইউআরএল থেকে দ্রুত (6oL687G0Iso)

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/references-guides/string-references-guide-for-swift/ দেখায় যে এটি ভালভাবে কাজ করে:

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

3
খেলার মাঠের সম্পাদন ব্যর্থ হয়েছে: ত্রুটি: <EXPR>: 23: 5: ত্রুটি: টাইপ 'স্ট্রিং.ইনডেক্স' প্রোটোকল 'ইন্টিজারলিটারাল কনভার্টেবল' স্ট্রিং = str.substringToIndex (1) to
বেন

0

ঠিক আছে, আমারও একই সমস্যা ছিল এবং "BridgeToObjectiveC ()" ফাংশনটি দিয়ে সমাধান করেছি:

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

দয়া করে নোট করুন যে উদাহরণস্বরূপ, এনএসমেকরেঞ্জের সাথে একত্রে স্ট্রিংউথ উইথরেঞ্জ সূচি 6 (অক্ষর "ডাব্লু") থেকে শুরু করে সূচক 6 + 6 পজিশনে সমাপ্ত (অক্ষর "!") এর অংশটি গ্রহণ করবে

চিয়ার্স।


আমি এটি ঘৃণা করি, তবে কেবল এটিই মনে হয় যা বেটা 4 এ আমার জন্য কাজ করছে
রোডেরিক ক্যাম্পবেল


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"
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.