Pour un habitué des expressions régulières (regex)

Philippe49Philippe49 Membre
décembre 2008 modifié dans API AppKit #1
Les NSPredicate sont compatibles avec les regex ICU's Regular Expressions, et permettent certaines analyses par regex des NSString et NSArray (entre autres).

Je merdoie sur le codage regex correspondant à  un nombre hexadécimal avec 6 à  8 chiffres

J'ai bien 0x[012345689abcdefABCDEF]{6,} ou 0x[0-9a-fA-F]{6,}, mais n'y a-t-il pas un codage pour les xdigit ?

Réponses

  • AliGatorAliGator Membre, Modérateur
    08:19 modifié #2
    Je connais mal les ICU mais bien les regex
    Moi j'aurais écrit comme toi (ou alors juste [0-9A-F] et en mode case insensitive) mais si tu veux une classe toute faite, essaye [:xdigit:] ?
  • Philippe49Philippe49 Membre
    décembre 2008 modifié #3
    [:xdigit:] fonctionne .


    Dans le lien que je signale, on met "The regular expression patterns and behavior are based on Perl's regular expressions."
  • AliGatorAliGator Membre, Modérateur
    08:19 modifié #4
    C'est pour ça que je t'ai proposé [:xdigit:], que je connais avec les PCRE ;)

    Mais bon y'a une différence avec les PCRE (Perl's Compatible Regular Expressions) et les regex classiques parfois... y'en a certains qui disent qu'ils supportent les regex mais en fait ne supportent pas toutes les subtilités comme le (?!xx) ou (?=xx) etc. (look-ahead/look-behind) qui sont pas toujours très utilisées (car pas très répandues sans doute aussi) donc pas implémentées partout non plus...

    Donc fallait qd mm vérifier ;)
  • Philippe49Philippe49 Membre
    08:19 modifié #5
    C'est ce qui est un peu pénible avec les regex : Tout le monde fait à  peu près pareil, mais pas tout à  fait, ou pas surement, en fait en lisant plus précisément le bouquin d'Oreilly sur les regex Perl, je lis qu'il faudrait faire :xdigit mais [:xdigit:] marche quand même !
    Autrement j'ai toujours admiré l'intelligence remarquable de la construction de ces regex.
  • AliGatorAliGator Membre, Modérateur
    08:19 modifié #6
    Ben figure-toi que j'ai failli te mettre :xdigit:, j'étais plus sûr s'il fallait un ou deux crochets (j'utilise rarement les classes de caractères comme ça)... En fait je me demande si c'est pas un peu aussi dépendant des systèmes...

    Bon après normalement quand ça te dit que ça supporte officiellement les PCRE (qui sont un standard il me semble, justement on dit pas juste "regex" mais "regex compatibles perl") et quand on voit en plus dans la doc sur les regex dans les ICU que ça supporte les look-ahead et look-behind qui sont loin d'être supportés par tous les moteurs de regex (c'est le truc le plus flagrant que les moteurs de regex laissent tomber en premier dans leur implémentation ça doit pas être simple à  intégrer), je pense que c'est quand même assez complet de ce côté, ce qui est une très bonne nouvelle d'ailleurs ma foi ;) Surtout pour des fans de regex comme nous toujours fascinés par la puissance que peuvent apporter ces bêtes-là  ^^
    (j'ai failli proposer la solution des regex d'ailleurs pour le post où il s'agissait de parser un bout de HTML, mais bon jamais encore eu l'occasion de les pratiquer en Cocoa)
  • Philippe49Philippe49 Membre
    décembre 2008 modifié #7
    Si cela intéress quelqu'un, voici un bout de code d'essai que j'ai mis mon Organizer (vraiment super cet outil XCode)

    #import <Foundation/Foundation.h>
    /* http://www.icu-project.org/userguide/regexp.html */
    int main(int argc, char *argv[]) {

    NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init];
    NSString * string = @..... ##### <\cost\">0.21<kk 0x12a0F kkk> <\"cost\">0.71 <  k  kk> <\"cost\">.22 <p> <\"cost\">.223 ";

    NSString * regex = @.*(cost(?!cost)){2}.*;  // exactement deux fois le mot 'cost'

    NSPredicate * regextest = [NSPredicate predicateWithFormat:@SELF MATCHES %@", regex];

    if ([regextest evaluateWithObject:string] == YES) {
    NSLog(@Match!);
    } else {
    NSLog(@No match!);
    }

    NSArray * array=[string componentsSeparatedByString:@cost];
    NSLog(@%@",array);
    NSString * regex2=@.*k +0x[:xdigit:]{3,} +k.*;
    NSPredicate * predicate = [NSPredicate predicateWithFormat:@SELF MATCHES %@", regex2];
    NSArray * filteredArray=[array filteredArrayUsingPredicate:predicate];
    NSLog(@%@",filteredArray);
    [pool drain];
    return 0;
    }



    Par contre, j'ai une petite question sur ces regex : y-a-t-il moyen d'extraire une partie de texte par les regex, via peut-être les captures de variables, comme le font sed ou d'autres commandes classiques ?


  • AliGatorAliGator Membre, Modérateur
    08:19 modifié #8
    Ben je sais pas avec les ICU, mais avec les PCRE oui bien sûr tu peux. Les parenthèses sont des éléments capturants, et ensuite tu peux les référencer (soit dans l'expression de la recherche, rare, ou plus souvent dans l'expression de remplacement ou pour l'extraction), à  l'aide de $1 ou \1 selon les syntaxes.

    Le problème c'est que je ne sais pas comment on fait en Cocoa : en général on utilise les PCRE pour faire un rechercher/remplacer par exemple, donc on utilise les références des expressions capturées dans la chaà®ne de remplacement (remplacer "(a)(b)" par "\2-\1" par exemple). Ou alors avec certaines APIs on demande de "matcher" la regex et ensuite on peux demander de récupérer l'expression capturée n°0 (totalité du texte matché) ou 1,2,3...

    Mais en Cocoa et avec les NSPredicate, je ne suis pas persuadé que ce soit possible...?
  • Philippe49Philippe49 Membre
    08:19 modifié #9
    dans 1230021854:

    Ben je sais pas avec les ICU, mais avec les PCRE oui bien sûr tu peux. Les parenthèses sont des éléments capturants, et ensuite tu peux les référencer (soit dans l'expression de la recherche, rare, ou plus souvent dans l'expression de remplacement ou pour l'extraction), à  l'aide de $1 ou \1 selon les syntaxes.


    Je connaissais $1 pour les remettre dans le regex,  mais pour faire l'extraction, il va falloir que je rebouquine ...
Connectez-vous ou Inscrivez-vous pour répondre.