Swift在字符串中的2个字符串之间获取字符串

alp*_*alp 34 string substring ios swift

我从html解析中得到一个字符串;

string = "javascript:getInfo(1,'Info/99/something', 'City Hall',1, 99);"
Run Code Online (Sandbox Code Playgroud)

我的代码是这样的

var startIndex = text.rangeOfString("'")
var endIndex = text.rangeOfString("',")
var range2 = startIndex2...endIndex
substr= string.substringWithRange(range)
Run Code Online (Sandbox Code Playgroud)

我不确定我的第二个分裂字符串应该是"'"还是"","

我想要我的结果

substr = "Info/99/something"
Run Code Online (Sandbox Code Playgroud)

ois*_*sdk 87

斯威夫特4

extension String {

    func slice(from: String, to: String) -> String? {

        return (range(of: from)?.upperBound).flatMap { substringFrom in
            (range(of: to, range: substringFrom..<endIndex)?.lowerBound).map { substringTo in
                String(self[substringFrom..<substringTo])
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

斯威夫特3

extension String {

    func slice(from: String, to: String) -> String? {

        return (range(of: from)?.upperBound).flatMap { substringFrom in
            (range(of: to, range: substringFrom..<endIndex)?.lowerBound).map { substringTo in
                substring(with: substringFrom..<substringTo)
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

老答案:

import Foundation

extension String {
  func sliceFrom(start: String, to: String) -> String? {
    return (rangeOfString(start)?.endIndex).flatMap { sInd in
      (rangeOfString(to, range: sInd..<endIndex)?.startIndex).map { eInd in
        substringWithRange(sInd..<eInd)
      }
    }
  }
}

"javascript:getInfo(1,'Info/99/something', 'City Hall',1, 99);"
  .sliceFrom("'", to: "',")
Run Code Online (Sandbox Code Playgroud)


seb*_*seb 20

我会使用正则表达式从复杂输入中提取子串.

Swift 3.1:

let test = "javascript:getInfo(1,'Info/99/something', 'City Hall',1, 99);"

if let match = test.range(of: "(?<=')[^']+", options: .regularExpression) {
    print(test.substring(with: match))
}

// Prints: Info/99/something
Run Code Online (Sandbox Code Playgroud)

Swift 2.0:

let test = "javascript:getInfo(1,'Info/99/something', 'City Hall',1, 99);"

if let match = test.rangeOfString("(?<=')[^']+", options: .RegularExpressionSearch) {
    print(test.substringWithRange(match))
}

// Prints: Info/99/something
Run Code Online (Sandbox Code Playgroud)


Sha*_*yag 15

要查找起始字符串和结束字符串之间的所有子字符串:

extension String {
    func sliceMultipleTimes(from: String, to: String) -> [String] {
        components(separatedBy: from).dropFirst().compactMap { sub in
            (sub.range(of: to)?.lowerBound).flatMap { endRange in
                String(sub[sub.startIndex ..< endRange])
            }
        }
    }
}

let str = "start A end ... start B end"
str.sliceMultipleTimes(from: "start", to: "end")    // ["A", "B"]
Run Code Online (Sandbox Code Playgroud)


pka*_*amb 10

我重写了 Swift 最重要的答案之一,以了解它对map. 我更喜欢使用guard, IMO的版本。

extension String {
    
    func slice(from: String, to: String) -> String? {
        guard let rangeFrom = range(of: from)?.upperBound else { return nil }
        guard let rangeTo = self[rangeFrom...].range(of: to)?.lowerBound else { return nil }
        return String(self[rangeFrom..<rangeTo])
    }
    
}

let test1 =   "a[b]c".slice(from: "[", to: "]") // "b"
let test2 =     "abc".slice(from: "[", to: "]") // nil
let test3 =   "a]b[c".slice(from: "[", to: "]") // nil
let test4 = "[a[b]c]".slice(from: "[", to: "]") // "a[b"
Run Code Online (Sandbox Code Playgroud)


Qby*_*yte 5

如果始终是第二次拆分,则此方法有效:

let subString = split(string, isSeparator: "'")[1]
Run Code Online (Sandbox Code Playgroud)


iAn*_*rag 5

您可以使用var arr = str.componentsSeparatedByString(",")第二个拆分来返回数组


Leo*_*bus 5

在 Swift 4 或更高版本中,您可以在 StringProtocol 上创建扩展方法来支持子字符串。您可以只返回 aSubstring而不是新字符串:

编辑/更新:Swift 5 或更高版本

extension StringProtocol  {
    func substring<S: StringProtocol>(from start: S, options: String.CompareOptions = []) -> SubSequence? {
        guard let lower = range(of: start, options: options)?.upperBound
        else { return nil }
        return self[lower...]
    }
    func substring<S: StringProtocol>(through end: S, options: String.CompareOptions = []) -> SubSequence? {
        guard let upper = range(of: end, options: options)?.upperBound
        else { return nil }
        return self[..<upper]
    }
    func substring<S: StringProtocol>(upTo end: S, options: String.CompareOptions = []) -> SubSequence? {
        guard let upper = range(of: end, options: options)?.lowerBound
        else { return nil }
        return self[..<upper]
    }
    func substring<S: StringProtocol, T: StringProtocol>(from start: S, upTo end: T, options: String.CompareOptions = []) -> SubSequence? {
        guard let lower = range(of: start, options: options)?.upperBound,
            let upper = self[lower...].range(of: end, options: options)?.lowerBound
        else { return nil }
        return self[lower..<upper]
    }
    func substring<S: StringProtocol, T: StringProtocol>(from start: S, through end: T, options: String.CompareOptions = []) -> SubSequence? {
        guard let lower = range(of: start, options: options)?.upperBound,
            let upper = self[lower...].range(of: end, options: options)?.upperBound
        else { return nil }
        return self[lower..<upper]
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

let string = "javascript:getInfo(1,'Info/99/something', 'City Hall',1, 99);"
let substr = string.substring(from: "'")                   // "Info/99/something', 'City Hall',1, 99);"
let through = string.substring(through: "Info")  // "javascript:getInfo"
let upTo = string.substring(upTo: "Info")  // "javascript:get"
let fromUpTo = string.substring(from: "'", upTo: "',")  // "Info/99/something"
let fromThrough = string.substring(from: "'", through: "',")  // "Info/99/something',"

let fromUpToCaseInsensitive = string.substring(from: "'info/", upTo: "/something", options: .caseInsensitive)  // "99"
Run Code Online (Sandbox Code Playgroud)


Dev*_*yas 5

斯威夫特 4.2:

extension String {

    //right is the first encountered string after left
    func between(_ left: String, _ right: String) -> String? {
        guard let leftRange = range(of: left), let rightRange = range(of: right, options: .backwards)
            ,leftRange.upperBound <= rightRange.lowerBound else { return nil }

        let sub = self[leftRange.upperBound...]
        let closestToLeftRange = sub.range(of: right)!
        return String(sub[..<closestToLeftRange.lowerBound])
    }

}
Run Code Online (Sandbox Code Playgroud)


Sco*_*des 5

雨燕5

extension String {
    /// Returns an array of substrings between the specified left and right strings.
    /// Returns an empty array when there are no matches.
    func substring(from left: String, to right: String) -> [String] {
        // Escape special characters in the left and right strings for use in a regular expression
        let leftEscaped = NSRegularExpression.escapedPattern(for: left)
        let rightEscaped = NSRegularExpression.escapedPattern(for: right)

        // Create a regular expression pattern to match content between the last occurrence of the left string
        // and the right string
        let pattern = "\(leftEscaped).*(?<=\(leftEscaped))(.*?)(?=\(rightEscaped))"

        // Create a regular expression object with the pattern
        guard let regex = try? NSRegularExpression(pattern: pattern, options: []) else {
            return []
        }

        // Find matches in the current string
        let matches = regex.matches(in: self, options: [], range: NSRange(startIndex..., in: self))

        // Extract the substrings from the matches and return them in an array
        return matches.compactMap { match in
            guard let range = Range(match.range(at: 1), in: self) else { return nil }
            return String(self[range])
        }
    }
}

// Example usage
let result = "cat cat dog rat".substring(from: "cat", to: "rat")
print(result) // Output: [" dog "]
Run Code Online (Sandbox Code Playgroud)