2016-12-27 91 views
1

我試圖拉出引號中的字符串的部分,即"Rouge One" is an awesome movie我想提取胭脂一號。查找字符串中的引號內的字符

這是我到目前爲止,但無法弄清楚從哪裏去:我創建一個文本的副本,以便我可以刪除第一個引號,以便我可以得到第二個索引。

if text.contains("\"") { 
    guard let firstQuoteMarkIndex = text.range(of: "\"") else {return} 
    var textCopy = text 
    let textWithoutFirstQuoteMark = textCopy.replacingCharacters(in: firstQuoteMarkIndex, with: "") 
    let secondQuoteMarkIndex = textCopy.range(of: "\"") 
    let stringBetweenQuotes = text.substring(with: Range(start: firstQuoteMarkIndex, end: secondQuoteMarkIndex)) 
} 

回答

1
var rouge = "\"Rouge One\" is an awesome movie" 

var separated = rouge.components(separatedBy: "\"") // ["", "Rouge One", " is an awesome movie"] 

separated.dropFirst().first 
+0

所有優秀的答案,但這是最輕量級滿足的需求。謝謝! – GarySabo

+0

@GarySabo **一般情況下**僅考慮此答案返回一個可選項+它不檢查是否有2個分隔符。這是一個骯髒但輕量級的答案。最好是用一個簡單的'if separated.count> 2 {其餘代碼}'進行檢查。或者簡單地做其他答案:D – Honey

3

無需創建副本或更換子這個任務。 以下是一種可能的方法:

  • 使用text.range(of: "\"")找到第一個引號。
  • 使用text.range(of: "\"", range:...)找到第二引號,即的範圍在步驟1
  • 提取兩個範圍之間的子找到的第一個後。

實施例:

let text = " \"Rouge One\" is an awesome movie" 

if let r1 = text.range(of: "\""), 
    let r2 = text.range(of: "\"", range: r1.upperBound..<text.endIndex) { 

    let stringBetweenQuotes = text.substring(with: r1.upperBound..<r2.lowerBound) 
    print(stringBetweenQuotes) // "Rouge One" 
} 

另一種選擇是用「正回顧後」和「積極的前瞻」圖案的正則表達式的搜索:

if let range = text.range(of: "(?<=\\\").*?(?=\\\")", options: .regularExpression) { 
    let stringBetweenQuotes = text.substring(with: range) 
    print(stringBetweenQuotes) 
} 
+0

很好地利用前瞻/後向。但是,像「'a」b「'這樣的字符串呢應該匹配嗎? – jtbandes

+0

@jtbandes:該代碼會提取前兩個引號之間的字符串(這是我如何理解該問題)。如果* all *引用的字符串是想要的,那麼你的方法就更好了 –

+0

你在做'r2.lowerBound'時忘了打開'r2',它應該是'r2!.lowerBound'。雖然我不明白爲什麼我不能'r2 ?.lowerBound' – Honey

1

另一種選擇是使用regular expressions找到對的報價:

let pattern = try! NSRegularExpression(pattern: "\\\"([^\"]+)\\\"") 

// Small helper methods making it easier to work with enumerateMatches(in:...) 
extension String { 
    subscript(utf16Range range: Range<Int>) -> String? { 
     get { 
      let start = utf16.index(utf16.startIndex, offsetBy: range.lowerBound) 
      let end = utf16.index(utf16.startIndex, offsetBy: range.upperBound) 
      return String(utf16[start..<end]) 
     } 
    } 

    var fullUTF16Range: NSRange { 
     return NSRange(location: 0, length: utf16.count) 
    } 
} 

// Loop through *all* quoted substrings in the original string. 
let str = "\"Rogue One\" is an awesome movie" 
pattern.enumerateMatches(in: str, range: str.fullUTF16Range) { (result, flags, stop) in 
    // rangeAt(1) is the range representing the characters in the 1st 
    // capture group of the regular expression: ([^"]+) 
    if let result = result, let range = result.rangeAt(1).toRange() { 
     print("This was in quotes: \(str[utf16Range: range] ?? "<bad range>")") 
    } 
} 
0

如果字符串數組計數> 2,我會用.components(separatedBy :)

let stringArray = text.components(separatedBy: "\"") 

檢查(至少有2個引號)。

檢查字符串數組數爲奇數,又名計數%2 == 1

  • 如果是奇數,所有偶數指數是2個引號之間,他們是你想要的。
  • 如果是偶數,所有的偶數索引-1都在2個引號之間(最後一個沒有結束引號)。

這將允許您也捕獲多套引用字符串,如: 「Rogue One」是一部「星球大戰」電影。