如何在Swift中逆正则表达式匹配[正则表达式否定]?

时间:2019-05-12 09:57:49

标签: ios swift regex regex-negation regex-lookarounds

是否有一种方法可以进行regular expression的逆匹配,并检索不匹配的字符串作为iOS Swift中的返回值?

比方说

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

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

正常比赛输出:“ lion

反比对输出:“ 232#$%4”(预期结果)

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

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中使用正则表达式模式本身来进行逆匹配,然后直接从输入字符串中检索不匹配的模式。

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

3 个答案:

答案 0 :(得分:1)

都使用此模式,但是由于不可预测,它不会反转{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从NSRange创建Range<String.Index>,反之亦然

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

var str = "232#$%4lion"
str.removeAll{$0.isLetter}

答案 1 :(得分:1)

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

app.post

快速测试:

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

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

答案 2 :(得分:0)

无需为此使用正则表达式。您可以只使用过滤器。 RangeReplaceableCollection有一个filter实例方法,该方法返回SelfString符合RangeReplaceableCollection,因此当与String一起使用时,filter返回另一个{{ 1}}。 您可以将其与新的String属性Character(Swift5)结合起来,并创建一个否定该属性的谓词。


isLetter