Регулярные выражения в swift - PullRequest
1 голос
/ 18 мая 2019

Меня немного смущает NSRegularExpression в swift, кто-нибудь может мне помочь?

задание: 1 задано ("name","john","name of john")тогда я должен получить ["name","john","name of john"].Здесь я должен избегать скобок.

задание: 2 задано ("name"," john","name of john")тогда я должен получить ["name","john","name of john"].Здесь я должен избежать скобок и лишних пробелов и, наконец, получить массив строк.

задание: 3 задано key = value // commentтогда я должен получить ["key","value","comment"].Здесь я должен получить только строки в строке, избегая = и //Я попробовал приведенный ниже код для задачи 1, но не прошел.

let string = "(name,john,string for user name)"
let pattern = "(?:\\w.*)"

do {
    let regex = try NSRegularExpression(pattern: pattern, options: .caseInsensitive)
    let matches = regex.matches(in: string, options: [], range: NSRange(location: 0, length: string.utf16.count))
    for match in matches {
        if let range = Range(match.range, in: string) {
            let name = string[range]
            print(name)
        }
    }
} catch {
    print("Regex was bad!")
}


Заранее спасибо.

Ответы [ 5 ]

1 голос
/ 18 мая 2019

Давайте рассмотрим:

let string = "(name,José,name is José)"

Я бы предложил регулярное выражение, которое ищет строки, где:

  • Это подстрока либо после ( в началеполная строка или после запятой, т. е. посмотрите за утверждением (?<=^\(|,);
  • Это подстрока, которая не содержит в себе ,, т. е. [^,]+?;
  • Этоподстрока, оканчивающаяся запятой или ) в конце полной строки, т. е. смотрите вперед утверждения (?=,|\)$) и
  • Если вы хотите, чтобы она пропускала пробелы до и послеподстроки, добавьте также \s*+.

Таким образом:

let pattern = #"(?<=^\(|,)\s*+([^,]+?)\s*+(?=,|\)$)"#
let regex = try! NSRegularExpression(pattern: pattern)
regex.enumerateMatches(in: string, range: NSRange(string.startIndex..., in: string)) { match, _, _ in
    if let nsRange = match?.range(at: 1), let range = Range(nsRange, in: string) {
        let substring = String(string[range])
        // do something with `substring` here
    }
}

Обратите внимание, я использую расширенные разделители строк Swift 5 (начиная с #" изаканчивая "#), чтобы мне не пришлось избегать обратной косой черты в строке.Если вы используете Swift 4 или более раннюю версию, вам понадобится экранировать обратную косую черту:

let pattern = "(?<=^\\(|,)\\s*+([^,]+?)\\s*+(?=,|\\)$)"
1 голос
/ 18 мая 2019

Разделите строку не алфавитно-цифровыми символами, кроме пробелов.Затем обрежьте элементы пробелами.

extension String {
    func words() -> [String] {
        return self.components(separatedBy: CharacterSet.alphanumerics.inverted.subtracting(.whitespaces))
                .filter({ !$0.isEmpty })
                .map({ $0.trimmingCharacters(in: .whitespaces) })
    }
}

let string1 = "(name,john,string for user name)"
let string2 = "(name,       john,name of john)"
let string3 = "key = value // comment"

print(string1.words())//["name", "john", "string for user name"]
print(string2.words())//["name", "john", "name of john"]
print(string3.words())//["key", "value", "comment"]
0 голосов
/ 18 мая 2019

Здесь я покончил с пониманием всех вышеприведенных комментариев.

let text = """
Capturing and non-capturing groups are somewhat advanced topics. You’ll encounter examples of capturing and non-capturing groups later on in the tutorial
"""

extension String {
            func  rex (_ expr : String)->[String] {
                return try! NSRegularExpression(pattern: expr, options: [.caseInsensitive])
                .matches(in: self, options: [], range: NSRange(location: 0, length: self.count))
                    .map {
                        String(self[Range($0.range, in: self)!])
                }
            }
        }
let r = text.rex("(?:\\w+-\\w+)") // pass any rex
0 голосов
/ 18 мая 2019

Один шаблон, работает для теста: 1 ... 3, в Swift.

let string =
    //"(name,john,string for user name)" //test:1
    //#"("name","       john","name of john")"# //test:2
    "key = value // comment" //test:3

let pattern = #"(?:\w+)(?:\s+\w+)*"# //Swift 5+ only
//let pattern = "(?:\\w+)(?:\\s+\\w+)*"

do {
    let regex = try NSRegularExpression(pattern: pattern)
    let matches = regex.matches(in: string, range: NSRange(0..<string.utf16.count))
    let matchingWords = matches.map {
        String(string[Range($0.range, in: string)!])
    }
    print(matchingWords) //(test:3)->["key", "value", "comment"]
} catch {
    print("Regex was bad!")
}
0 голосов
/ 18 мая 2019

RegEx в Swift

Эти сообщения могут помочь вам изучить регулярные выражения в swift:

Задание 1 и 2

Это выражение может помочь вам сопоставить желаемые результаты для задач 1 и 2:

"(\s+)?([a-z\s]+?)(\s+)?"

enter image description here


Основываясь на совете Роба , вы можете значительно сократить границы, например, список символов [a-z\s]. Например, здесь мы также можем использовать:

"(\s+)?(.*?)(\s+)?"

или

"(\s+)?(.+?)(\s+)?"

для простой передачи всего между двумя " и / или пробелом .

enter image description here

RegEx

Если это не было вашим желаемым выражением, вы можете изменить / изменить выражения в regex101.com .

RegEx Circuit

Вы также можете визуализировать свои выражения в jex.im :

enter image description here

Демонстрация JavaScript

const regex = /"(\s+)?([a-z\s]+?)(\s+)?"/gm;
const str = `"name","john","name of john"
"name","       john","name of john"
"       name  ","       john","name of john     "
"       name  ","       john","       name of john     "`;
const subst = `\n$2`;

// The substituted value will be contained in the result variable
const result = str.replace(regex, subst);

console.log('Substitution result: ', result);

Задание 3

Это выражение может помочь вам разработать выражение для третьей задачи:

(.*?)([a-z\s]+)(.*?)

enter image description here

const regex = /(.*?)([a-z\s]+)(.*?)/gm;
const str = `key = value // comment
key = value with some text // comment`;
const subst = `$2,`;

// The substituted value will be contained in the result variable
const result = str.replace(regex, subst);

console.log('Substitution result: ', result);
...