[résolu: trop de fatigue] Ce sont mes yeux ou quoi ?

CéroceCéroce Membre, Modérateur
mars 2015 modifié dans API AppKit #1
J'ai écrit le programme suivant:

Une méthode de remplacement des tokens {jour} et {période}:
 
#import "TextReplacement.h"

@implementation TextReplacement

+ (NSString *) stringByReplacingTokensInString:(NSString *)sourceString {
NSMutableString *text = [NSMutableString stringWithString:sourceString];
const NSRange wholeTextRange = NSMakeRange(0, text.length);

NSString *dayString = @Aujourd'hui;
[text replaceOccurrencesOfString:@{jour} withString:dayString options:0 range:wholeTextRange];

NSString *periodString = @Matin;
[text replaceOccurrencesOfString:@{période} withString:periodString options:0 range:wholeTextRange];

return [text copy];
}

@end
Et de quoi l'exercer:
 
#import <Foundation/Foundation.h>
#import "TextReplacement.h"

int main(int argc, const char * argv[]) {
@autoreleasepool {
// This one works
NSString *sourceString0 = @{période} {jour};
NSLog(@Before: %@ | after: %@", sourceString0, [TextReplacement stringByReplacingTokensInString:sourceString0]);

// But not this one
NSString *sourceString1 = @{jour} {période};
NSLog(@Before: %@ | after: %@", sourceString1, [TextReplacement stringByReplacingTokensInString:sourceString1]);
}
return 0;
}
Je m'attends à  ce que le remplacement fonctionne les deux fois, mais ça ne marche que dans le premier cas. Y comprenez-vous quelque chose ?!

Voici le projet:

Réponses

  • LarmeLarme Membre

    wholeTextRange, alors que le range risque de changer vu que tu fais du remplacement ?


  • CéroceCéroce Membre, Modérateur
    mars 2015 modifié #3
    Bien vu...

    Bon, ben ce sont mes yeux alors ! Merci beaucoup, dur dur de comprendre après une journée de codage ;-)
  • LarmeLarme Membre
    mars 2015 modifié #4

    C'est corrigé du coup ? ie. range:wholeTextRange => range:[text length]


     


    Je pense que c'était le soucis, vu que {jour} fait 6 et le texte qui le remplace fait 11 caractères de long (à  une erreur près).

    Du coup, on risque de sortir du range quand tu veux effectuer ton deuxième remplacement.


    Ce qui dans le cas de {période} fonctionnait car le string de remplacement était plus court.


     


     


    à‰dit: ça a été marqué en résolu entre temps.


  • Joanna CarterJoanna Carter Membre, Modérateur
    Tu n'utilises pas les regex ?
  • CéroceCéroce Membre, Modérateur
    mars 2015 modifié #6
    Il y avait une blague:

    J'avais un problème, j'ai donc utilisé les regex pour le résoudre. Maintenant j'ai deux problèmes.


    Non, je n'utilise pas les regex, c'est lourd à  utiliser, et toujours difficile à  mettre au point. Les tokens ont ici une forme fixe, ma solution convient très bien, parce que je n'ai pas besoin de savoir où se trouvent les token et les interpréter; c'est un simple remplacement.
  • FKDEVFKDEV Membre

    J'utilise les regex de manière temporaire pour faire des rechercher/remplacer évolué quand je transforme des données ou des sources (dans TextWrangler ou Visual Studio).


     


    Je ne les utilise pas dans les sources car je suis incapable de les relire et encore moins de les corriger 6 mois après.


    Il faut vraiment avoir des tests unitaires carrés pour cela.


     


    Je ne les utilise pas en validation de saisie utilisateur car j'en fais peu et quand j'en fais, je traite les chaà®nes de manière artisanale.


  • LarmeLarme Membre

    Des regex seraient un peu overkill dans le cas simple avec des "placeholders" où un simple remplacement de texte fait l'affaire, non ?


     


    Les regex c'est bien, mais c'est pas forcément évident.


  • AliGatorAliGator Membre, Modérateur
    mars 2015 modifié #9
    Les RegEx ce n'est pas si compliqué une fois qu'on s'est plongé dedans, surtout pour si peu. Et surtout, avec l'option "x" permettant d'ignorer les espaces et les commentaires, on peut l'aérer et la commenter pour + de lisibilité. Mais c'est effectivement de l'overkill pour ce cas là .

    Voici ma proposition comme alternative pour la méthode de Ceroce, méthode de catégorie sur NSString (car ça me parait plus intuitif, mais c'est affaire de goût) que j'ai fait plus générique en prenant un dictionnaire de remplacements en paramètre.
    @interface NSString (CETokenReplacement)
    - (NSString*)stringByReplacingTokens:(NSDictionary*)tokens;
    @end
    @implementation NSString (CETokenReplacement)
    - (NSString*)stringByReplacingTokens:(NSDictionary*)tokens
    {
    NSMutableString *text = [self mutableCopy];
    [tokens enumerateKeysAndObjectsUsingBlock:^(NSString* token, NSString* repl, BOOL *stop) {
    [text replaceOccurrencesOfString:token withString:repl options:0 range:NSMakeRange(0, text.length)];
    }];
    return [text copy];
    }
    @end
    Exemple d'usage :
    NSString* origStr = @Nous sommes {jour} et c'est le {période} !;
    NSString* newStr = [origStr stringByReplacingTokens:@{@{jour}:@Aujourd'hui, @{période}:@Matin}];
  • olofolof Membre

    Et pour aider à  comprendre une regexp, il y a ce site : http://regexper.com/


  • Joanna CarterJoanna Carter Membre, Modérateur
    Et pour les tester http://rubular.com
  • CéroceCéroce Membre, Modérateur
    mars 2015 modifié #12

    C'est justement ce qu'on reproche aux regex, non ? Il faut 1) les comprendre et 2) les tester.


     


    Je précise que j'ai pas mal travaillé avec autrefois (un outil en Python pour faire des extractions dans du code source), et que je n'ai pas de problème avec le principe, mais je suis convaincu que si on peut s'en passer, il faut.


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