swift 中的正则表达式

Regular expressions in swift

我对 swift 中的 NSRegularExpression 有点困惑,有人可以帮助我吗?

任务: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!")
}


提前致谢。

Swift

中的正则表达式

这些帖子可能会帮助您探索 swift:

中的正则表达式
  • How to group search regular expressions using swift?

任务 1 和 2

此表达式可能会帮助您匹配任务 1 和 2 所需的输出:

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


根据Rob的建议,您可以大大减少边界,例如字符列表[a-z\s]。例如这里,我们还可以使用:

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

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

简单地传递两个 " and/or space.

之间的所有内容

正则表达式

如果这不是您想要的表达方式,您可以 modify/change 在 regex101.com 中表达您的表达方式。

正则表达式电路

您还可以在 jex.im:

中可视化您的表情

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`;

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

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

任务 3

This expression可能会帮助你为第三个任务设计一个表达式:

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

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

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

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

用除空格外的非字母数字字符分隔字符串。然后 trim 带有空格的元素。

extension String {
    func words() -> [String] {
        return self.components(separatedBy: CharacterSet.alphanumerics.inverted.subtracting(.whitespaces))
                .filter({ ![=10=].isEmpty })
                .map({ [=10=].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"]

单一模式,适用于 test: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([=10=].range, in: string)!])
    }
    print(matchingWords) //(test:3)->["key", "value", "comment"]
} catch {
    print("Regex was bad!")
}

让我们考虑一下:

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

我建议使用正则表达式来查找字符串,其中:

  • 它是完整字符串开头的 ( 之后或逗号之后的子字符串,即查看 (?<=^\(|,);
  • 的断言后面
  • 是不包含,的子串,即[^,]+?
  • 它是在完整字符串末尾以逗号或 ) 终止的子字符串,即 (?=,|\)$)
  • 的前瞻断言
  • 如果你想让它跳过子字符串前后的白色 space,也加入 \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*+(?=,|\)$)"

在理解了以上所有评论后,我在这里完成了。

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([=10=].range, in: self)!])
                }
            }
        }
let r = text.rex("(?:\w+-\w+)") // pass any rex