如何在 Swift 中进行反向正则表达式匹配 [正则表达式否定]?

How to do Inverse Regex match [regex negation] in Swift?

有没有办法进行反向 regular expression 匹配并将不匹配的字符串检索为 iOS Swift 中的 return 值?

假设,

输入字符串:“232#$%4lion

正则表达式模式:“[a-z]{4}

正常匹配输出:“lion

反向匹配输出:“232#$%4”(预期结果)

请在下面找到正常的正则表达式匹配 swift 代码。

func regexMatch() {

    let str = "232#$%4lion"

    let regex = try! NSRegularExpression(pattern: "[a-z]{4}", options: .caseInsensitive)
    let firstMatch = regex.firstMatch(in: str, options: .reportProgress, range: NSMakeRange(0, str.count))
    guard let matches = firstMatch else {
        print("No Match")
        return
    }

    if matches.numberOfRanges > 0 {
        let outputRange = matches.range(at: 0)
        let startIndex = str.index(str.startIndex, offsetBy: outputRange.lowerBound)
        let endIndex = str.index(str.startIndex, offsetBy: outputRange.upperBound)
        print("Matched String: \(str[startIndex..<endIndex])")
    }
}

我可以以某种方式操纵匹配结果,然后可以通过操纵范围操作来检索反向匹配字符串。而不是那样做, 我想知道是否可以在 Swift 中使用正则表达式模式本身来完成反向匹配,并直接从输入字符串中检索不匹配的模式。

以上输入输出值仅供参考。只是为了让问题简单。实时情况下的实际值可能很复杂。请用通用的解决方案回答。

要么使用此模式,但它不会反转 {4} 因为它不可预测

"[^a-z]+"

或者从 str 创建一个新的可变字符串并删除找到的范围

func invertedRegexMatch() {

    let str = "232#$%4lion"

    let regex = try! NSRegularExpression(pattern: "[a-z]{4}", options: .caseInsensitive)
    let firstMatch = regex.firstMatch(in: str, options: .reportProgress, range: NSRange(str.startIndex..., in: str))
    guard let matches = firstMatch else {
        print("No Match")
        return
    }

    if matches.numberOfRanges > 0 {
        let outputRange = Range(matches.range(at: 0), in: str)!
        var invertedString = str
        invertedString.removeSubrange(outputRange)
        print("Matched String: \(invertedString)")
    }
}

注意:始终使用专用API从Range<String.Index>创建NSRange,反之亦然

但是如果你只想删除所有字母,有一种更简单的方法

var str = "232#$%4lion"
str.removeAll{[=12=].isLetter}

不需要为此使用正则表达式。你可以只使用过滤器。 RangeReplaceableCollection 有一个 filter 实例方法 returns SelfString 符合 RangeReplaceableCollection,所以在与 String 一起使用时进行过滤returns 另一个 String。 您可以将它与新的 Character 属性 isLetter (Swift5) 结合起来并创建一个否定 属性.

的谓词
let str = "232#$%4lion"
let result = str.filter { ![=10=].isLetter }
print(result)   // "232#$%4"

您可以使用正则表达式删除(替换为空字符串)找到的匹配项:

let result = str.replacingOccurrences(of: "[a-z]{4}", with: "", options: .regularExpression)

Swift 测试:

let str = "232#$%4lion"
let result = str.replacingOccurrences(of: "[a-z]{4}", with: "", options: .regularExpression)
print(result) 

输出:232#$%4.