Swift 3 - Supprimer caractères spéciaux (TAB, ...)

PatyomPatyom Membre
mai 2017 modifié dans Objective-C, Swift, C, C++ #1

Bonjour à  tous


 


Je suis en train de tourner en rond car je n'arrive pas à  trouver l'instruction pour retirer les caractères tels que : TAB, RC dans une chaine de caractères.


Je n'ai pas trop de connaissance en Swift, disons que j'apprends vite parce que j'ai déjà  un bon passé en programmation.


 


Si quelqu'un pouvait me guider pour avancer dans la maitrise de Swift.


 


Merci   ;)  ;)


Réponses

  • DrakenDraken Membre
    juin 2017 modifié #2

    // texte à  filtrer
    let texte = "abcdef 0123456789"
    // Liste des caractères à  éliminer
    let listeFiltrage:Set<Character> = ["b", "c", "e", "3", "8", "2"]

    let filtrage = String(texte.characters.filter {!listeFiltrage.contains($0)})
    print ("Avant : ",texte)
    print ("Après : ",filtrage)


    a



     


    Avant :  abcdef 0123456789


    Après :  adf 0145679


     


    a


    Explications demain, là  .. dodo !


     


    Et n'hésite pas à  te présenter ici : http://forum.cocoacafe.fr/forum/17-présentation-des-membres/


     


    On peut aussi définir les caractères à  éliminer sous la forme d'une chaà®ne, avec cette syntaxe :


    a



    let listeFiltrage = Set("bce382".characters)

    a


    EDIT : Encodage d'un caractère spécial sous forme d'un Character


    a



    let caractereTAB:Character = "\u{09}"

    a

  • DrakenDraken Membre
    juin 2017 modifié #3

    Explication : .filter() permet de filtrer le contenu d'un tableau, avec un test indiquant si un élément doit être gardé ou éliminé.


     


    Appliqué à  une String, l'opérateur .Characters transforme celle-ci en un tableau de Characters.



    let filtrage = String(texte.characters.filter {!listeFiltrage.contains($0)})

    La condition de filtrage est l'appartenance à  un Set (groupe) de caractères, ou plutôt la non-appartenance puisque j'ai ajouté l'opération de négation binaire (!).


     


    En une seule ligne, j'indique à  Swift de :


    - créer un tableau de caractères à  partir d'une chaà®ne


    - parcourir ce tableau et en créer un nouveau en recopiant chaque caractère, sauf ceux contenus dans listeFiltrage


    - créer une nouvelle chaà®ne à  partir du tableau de copie


  • CéroceCéroce Membre, Modérateur

    Je trouve que le nom "filtrage" dans ton exemple est mal choisi, parce que ça fait penser qu'il s'agit d'une closure à  appliquer pour filtrer.


    J'aurais plutôt appelé la variable "texteFiltré".


    Vois-tu ce que je veux dire ?


  • DrakenDraken Membre
    juin 2017 modifié #5

    Tu as raison, mais je plaide qu'il était 1h30 du matin quand j'ai tapé ça en vitesse.. 


  • DrakenDraken Membre
    juin 2017 modifié #7

    Honte à  moi. Je devrais lire la doc Apple en entier, un de ces jours ..


    EDIT : Sauvé de la honte par Ceroce, qui a lu la doc


  • CéroceCéroce Membre, Modérateur



     


    Attention, ça n'ôte les caractères qu'en début et fin de chaà®ne.

  • Joanna CarterJoanna Carter Membre, Modérateur

    Trouvé sur SO :



    extension String
    {
    func condenseWhitespace() -> String
    {
    return self.components(separatedBy: CharacterSet.whitespacesAndNewlines)
    .filter { !$0.isEmpty }
    .joined(separator: " ")
    }
    }


    let bonString = mauvaisString.condenseWhitespace()
  • DrakenDraken Membre
    juin 2017 modifié #10

    C'est pas bête d'utiliser une extension.


    a



    extension String {
    func nettoyage(intrus:String) -> String {
    let listeFiltrage = Set(intrus.characters)
    return String(self.characters.filter {
    !listeFiltrage.contains($0)
    })
    }
    }


    a



    let apresNettoyage = texte.nettoyage(intrus: "bce382\u{09}")

    a


  • Joanna CarterJoanna Carter Membre, Modérateur

    C'est pas bête d'utiliser une extension.




    Mais ce n'est pas nécessaire de passer le paramètre. On devrait jouer avec self
  • Le paramètre c'est la liste des caractères à  exclure de la chaine.


     


    L'exclusion de ton extension n'est pas paramétrable, contrairement à  la mienne.


     


    mais effectivement on pourrait écrire :



    extension String {
    func nettoyageInterne() -> String {
    let listeFiltrage = Set("bce382\u{09}".characters)
    return String(self.characters.filter {
    !listeFiltrage.contains($0)
    })
    }
    }


    a



    let apresNettoyage = texte.nettoyageInterne()

    a

  • PatyomPatyom Membre
    juin 2017 modifié #13

    hola, pas mal vos réponses, je les ai testé mais j'ai toujours un pb avec des espaces devant mon texte.


     


    j'ai utilisé ce code :



    page.texteDefinitif = page.texteDefinitif?.replacingOccurrences(of: "[\t\n\r]", with: "",options: .regularExpression)

    et cette ligne pour ensuite ôter les espaces mais je ne suis pas convaincu. 




    page.texteDefinitif = page.texteDefinitif?.replacingOccurrences(of: " ", with: "",options: .regularExpression)

    Pour l'instant il y a toujours 6 espaces devant, je n'aime pas le code ci-dessus pour retirer les espaces, j'aurais préféré une instruction type pour retirer ces espaces devant, instruction du genre "Trim" beaucoup plus sûr.


     


    Bon j'avance, c'est déjà  bien.


  • DrakenDraken Membre
    juin 2017 modifié #14

    Le plus simple c'est de nous montrer ce que tu veux exactement. Un exemple de texte "avant" et un exemple "après".


     


    Si as TOUJOURS 6 espaces vide devant tes chaà®nes, il suffit de créer une nouvelle chaà®ne en copiant les caractères à  partir de la 7iéme position.

  • Joanna CarterJoanna Carter Membre, Modérateur
    juin 2017 modifié #15

    Je viens de tester ma solution et ça marche nickel.



    extension String
    {
    func condenseWhitespace() -> String
    {
    return self.components(separatedBy: CharacterSet.whitespacesAndNewlines)
    .filter { !$0.isEmpty }
    .joined(separator: " ")
    }
    }


    let str = " \t \n fred \t is cool "

    let trimmed = str.condenseWhitespace()

    print(trimmed)

    Resultat : "fred is cool"


  • Joanna CarterJoanna Carter Membre, Modérateur
    juin 2017 modifié #16

    Si tu voulais seulement supprimer avant et après mas pas dans :



    let trimmed = str.trimmingCharacters(in: .whitespacesAndNewlines)

    Ce qui te donnerait "fred   \t  is   cool"


  • PatyomPatyom Membre
    juin 2017 modifié #17

    cool,


    C'est exactement ce qu'il me fallait.


     


    Pourrais-tu m'expliquer les différentes lignes dans le "func", toi ou un autre.



    .joined(separator: " "

    çà  j'ai saisi


     


    par contre le "self" çà  doit correspondre au texte à  modifier et que l'on retourne, non ?


  • Joanna CarterJoanna Carter Membre, Modérateur
    juin 2017 modifié #18

    func condenseWhitespace() -> String
    {
    return self.components(separatedBy: CharacterSet.whitespacesAndNewlines) // créer components

    .filter { !$0.isEmpty } // filtrer les components en ignorant les vides

    .joined(separator: " ") // rassembler les components en string
    }

    En effet, on appelle trois méthodes, l'une après l'autre, en utilisant le résultat de la méthode précédente suivi par le "."




  •  


    par contre le "self" çà  doit correspondre au texte à  modifier et que l'on retourne, non ?




     


    Oui et non, le self correspond à  la valeur d'entrée de l'extension (le texte que l'on doit modifier). Mais le résultat retourné est une variable intermédiaire générée par le compilateur. Self n'est pas modifié pendant l'opération.

  • Joanna CarterJoanna Carter Membre, Modérateur
    juin 2017 modifié #20


    cool,


    C'est exactement ce qu'il me fallait.




     


    Mais c'est exactement ce que je t'ai dit hier : http://forum.cocoacafe.fr/topic/15248-swift-3-supprimer-caractères-spéciaux-tab/?p=147414   ::)


  • PatyomPatyom Membre
    juin 2017 modifié #21

    Sorry


    il semble que j'ai zapper ton post hier, j'ai lu tous les posts dans la foulée mais il semble que je me sois concentré sur un en particulier.


    Ton explication est parfaite, je note


    Ok Draken j'ai saisi pour le "Self".


     


    Si j'ai d'autres questions je ne manquerai pas de vous solliciter.


     


    Merci pour vos réponses.

Connectez-vous ou Inscrivez-vous pour répondre.