2016-12-27 3 views
1

Я пытаюсь вытащить части строки, которые находятся в кавычках, т. Е. В "Rouge One" is an awesome movie Я хочу извлечь Rouge One.Найти символы внутри кавычек в String

Это то, что у меня есть до сих пор, но не могу понять, куда идти отсюда: создаю копию текста, чтобы удалить первый кавычек, чтобы я мог получить индекс второго.

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 separate.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

Хорошее использование lookahead/lookbehind. Но, как насчет строки, такой как «a» b? »? Должны ли они совпадать? – jtbandes

+0

@jtbandes: этот код будет извлекать строку между двумя первыми кавычками (как я понял вопрос). Если * all * цитируемые строки нужны, тогда ваш подход лучше. –

+0

Вы забыли развернуть 'r2' при выполнении' r2.lowerBound', он должен быть '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

Я хотел бы использовать .components (separatedBy :)

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

Проверьте, если счетчик StringArray> 2 (есть по крайней мере, 2 цитаты).

Проверьте счетчик StringArray нечетный, иначе подсчитывать% 2 == 1.

  • Если это странно, все четные индексы от 2 цитаты и они, что вы хотите.
  • Если он четный, все четные индексы - 1 находятся между двумя кавычками (у последней нет котировки).

Это позволит вам также захватить несколько наборов цитируемых строк, например: «Rogue One» - это фильм «Звездные войны».

Смежные вопросы