Как использовать регулярные выражения в Swift для захвата строки между двоеточиями - PullRequest
2 голосов
/ 15 апреля 2019

Получить некоторую строку любой длины, возвращенную из бэкэнда как "junkasdojf :text:"

Как бы я использовал выражение reg для возврата чистой строки как ":text:" (двоеточия должны быть включены)

Предпочтительно быстрый способ справиться с этим.Раньше я не использовал regex, но я читал, что это единственный способ решить эту проблему, кроме грязных расколов и реконструкции.

Это то, что у меня есть, но я не уверен, как продвигаться

let regex = try? NSRegularExpression(pattern: ":[a-z]:", options: .caseInsensitive)

Ответы [ 4 ]

3 голосов
/ 15 апреля 2019

Было бы проще использовать range(of:options:).

let someStr = "junkasdojf :text:"
if let substrRange = someStr.range(of: ":[a-zA-Z]+:", options: .regularExpression) {
    print("Match = \(someStr[substrRange])")
} else {
    print("No match")
}
1 голос
/ 15 апреля 2019

Ответ rmaddy будет предпочтительным способом для простой неповторяющейся задачи, и ответ AamirR кажется правильным решением, если вы не возражаете против использования NSString в коде Swift.

Но основнойиспользование NSRegularExpression со Swift String будет примерно таким:

let str = "junkasdojf :text:"

//You can use `try!` when you are sure your pattern is valid.
//And do not miss `+` after `[a-z]`.
let regex = try! NSRegularExpression(pattern: ":[a-z]+:", options: .caseInsensitive)
//Use `str.utf16.count`, not `str.count`.
if let match = regex.firstMatch(in: str, range: NSRange(0..<str.utf16.count)) {
    //Use `Range.init(_:in:)` to convert `NSRange` to `Range<String.Index>`.
    let range = Range(match.range, in: str)!
    //When you can accept `Substring`, `String.init(_:)` is not needed.
    let matchingStr = String(str[range])
    print(matchingStr) //->:text:
} else {
    print("*NO mathes*")
}
1 голос
/ 15 апреля 2019

Более общим способом является использование группы захвата:

let pattern = "junkasdojf\\s*(:[^:]*:)"

Пример кода Swift:

let str = "Some string here, junkasdojf :text: and more here"
let pattern = "junkasdojf\\s*(:[^:]*:)"
do {
    let regex = try NSRegularExpression(pattern: pattern)
    if let match = regex.firstMatch(in: str, range: NSRange(str.startIndex..., in: str)) {
        let result = str[Range(match.range(at: 1), in: str)!]
        print(String(result))
    }
} catch { print(error) }

См. демонстрационное выражение regex .

Здесь junkasdojf соответствует подстроке, которая является левым контекстом для нужной вам строки, \s* соответствует 0+ пробелов, а (:[^:]*:) вводит в группу 1 двоеточие, любое 0+ символы, отличные от :, а затем :.

В качестве альтернативы, если количество пробелов между junkasdojf и : не может превышать некоторый максимальный порог, вы можете использовать ограниченное значение с поддержкой ширины канала :

let s = "Some string here, junkasdojf :text: and more here"
if let rng = s.range(of: ":(?<=junkasdojf\\s{0,1000}:)[^:]*:", options: .regularExpression) {
    print(s[rng])
}

Это не сработает в regex101, так как не поддерживает ICU-регулярное выражение, но при этом предполагается, что между junkasdojf и пробелами может быть не более 1000 пробелов.следующий :.:(?<=junkasdojf\\s{0,1000}:)[^:]*: соответствует :, затем проверяется, что junkasdojf сопровождается от 0 до 1000 пробелов и : (это необходимо для привязки к первому :), а затем [^:]* соответствует нулю или болеесимволы, отличные от :, а затем : соответствует :.

Кроме того, если вас интересует самое короткое из возможных регулярных выражений, но вы можете заменить входную строку регулярным выражением, используя

let s = "Some string here, junkasdojf :text: and more here"
let result = s.replacingOccurrences(of: "(?s).*junkasdojf\\s*(:[^:]*:).*", with: "$1", options: .regularExpression, range: nil)
print(result) 

Выход: :text:.

См. Демонстрационное регулярное выражение

Подробности

  • (?s) - модификатор, который позволяет . сопоставлять символы разрыва строки
  • .* - любые 0+ символов максимально возможного числа
  • junkasdojf - подстрока
  • \\s* - 0+ пробелов
  • (:[^:]*:) - Группа захвата 1 ($1): двоеточие, 0 или более символов, отличных от :, двоеточие
  • .* - любые 0+ символов как можно больше
1 голос
/ 15 апреля 2019

Следующий будет соответствовать несколько вхождений

// \w matches any word character such as [a-zA-Z0-9_]
let regex = try! NSRegularExpression(pattern: ":\\w+:")

let nsString: NSString = "junkasdojf :text: flkasdj junkasdojf :two:"
let matches = regex.matches(in: nsString as String, options: [], range: NSMakeRange(0, nsString.length))
for match in matches {
    print(nsString.substring(with: match.range))
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...