3
votes

Comment faire correspondre Inverse Regex [négation regex] dans Swift?

Existe-t-il un moyen de faire correspondre expression régulière inverse et de récupérer la chaîne qui ne correspond pas comme valeur de retour dans iOS Swift ?

Disons,

Chaîne d'entrée: " 232 # $% 4lion "

Modèle d'expression régulière: " [az] {4} code> "

Résultat de correspondance normale:" lion "

Résultat de correspondance inverse:" 232 # $% 4 "( Résultat attendu)

Veuillez trouver ci-dessous le code SWIFT correspondant à l'expression régulière régulière.

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])")
    }
}

Je peux en quelque sorte manipuler le résultat de la correspondance et ensuite récupérer la correspondance inverse chaîne en manipulant les opérations de plage. Au lieu de faire ça, Je veux savoir si la correspondance inverse peut être effectuée en utilisant le modèle regex lui-même dans Swift et récupérer directement le modèle non correspondant à partir de la chaîne d'entrée.

Les valeurs d'entrée et de sortie ci-dessus sont uniquement à titre de référence. Juste pour garder la question simple. Les valeurs réelles dans les cas en temps réel peuvent être complexes. Veuillez répondre avec une solution générique.


5 commentaires

Vous pouvez remplacer la correspondance par une chaîne vide laissant 232 # $% 4


Remplacez simplement comme le 4ème oiseau le suggère: let result = string.replacingOccurrences (of: "[a-z] {4}", with: "", options:. Regular Expression)


Merci @Thefourthbird. Ca a du sens.


Merci @ WiktorStribiżew. Veuillez publier votre solution comme réponse. Je peux voter et accepter.


Ok, posté avec des explications.


3 Réponses :


1
votes

Utilisez ce modèle, mais il n'inverse pas {4} car il n'est pas prévisible

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

ou créez une nouvelle chaîne mutable à partir de str et supprimez la plage trouvée

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)")
    }
}

Remarque: utilisez toujours l'API dédiée pour créer NSRange à partir de Range et vice versa

Mais si vous voulez simplement supprimer toutes les lettres, il existe un moyen beaucoup plus simple

"[^a-z]+"


0 commentaires

0
votes

Il n'est pas nécessaire d'utiliser une expression régulière pour cela. Vous pouvez simplement utiliser le filtre. RangeReplaceableCollection dispose d'une méthode d'instance de filter qui renvoie Self , String est conforme à RangeReplaceableCollection , donc le filtre lorsqu'il est utilisé avec une String renvoie une autre String . Vous pouvez le combiner avec la nouvelle propriété Character isLetter (Swift5) et créer un prédicat annulant cette propriété.


let str = "232#$%4lion"
let result = str.filter { !$0.isLetter }
print(result)   // "232#$%4"


1 commentaires

Merci pour votre temps. Je veux savoir comment faire de la négation des regex en Swift. Les exemples de texte donnés sont juste à titre de référence. Quoi qu'il en soit, j'ai appris une nouvelle chose ici: "isLetter" dans Swift 5. Encore une fois, merci.



1
votes

Vous pouvez utiliser votre expression régulière pour supprimer (remplacer par une chaîne vide) les correspondances trouvées:

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

Test Swift:

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

Sortie: 232#$%4.


0 commentaires