Problème avec MOKit

TchouboudouTchouboudou Membre
09:17 modifié dans Actualités #1
Bonsoir tout le monde.

J'utilise depuis très récemment MOKit. Je l'ai donc testé et essayé un peu. Malheuresement, j'ai un petit problème.

J'ai une chaà®ne : <gras>test</gras><gras>retest</gras>

Ma Regex est la suivante : [MORegularExpression regularExpressionWithString: @(<gras>(.+)</gras>)+ ignoreCase:YES];

Le problème, quand je récupère ce qu'il y a entre les balises, ça ne me donne pas 2 résultat, mais un seul : test</gras><gras>retest.
En PHP, il existe : 'U' pour éviter ça. Mais en "MOKit", comment fait-on ?

Merci d'avance,
Tchouboudou

Réponses

  • schlumschlum Membre
    mai 2007 modifié #2
    Ce n'est pas vraiment du Cocoa, donc je pense que le sujet devrait être replacé dans la programmation en général (encore que, c'est même pas de la programmation  :P)

    Il faut utiliser la notion d'expression "paresseuse", car une expression régulière est gourmande par défaut.

    -> "(<gras>(.+?)</gras>)+"

    Les quantificateurs gourmands sont {}, ?, *, +
    Les quantificateurs paresseux qui correspondent sont {}?, ??, *?, +?
  • Philippe49Philippe49 Membre
    09:17 modifié #3

    En gros c'est quoi MOKit ? Sur le site, il parle d'extension de Cocoa

    MOKit is a Mac OS X framework that extends the Cocoa development frameworks. The project includes the framework itself as well as several supporting pieces that are all built by a single Project Builder project.
    MOKit serves two main purposes.
    First, MOKit is a useful collection of classes, categories, and functions that extend Apple's Cocoa frameworks. It may be used by other Cocoa projects by dragging the built framework into an existing project and choosing which targets should link with it.
    Second, MOKit is maintained as an example of the best practices for structuring and deploying a useful third-party framework for Mac OS X. The Project Builder project has been carefully set up to do everything according to current best practices and should be updated quickly any time such best practices change.
  • schlumschlum Membre
    09:17 modifié #4
    C'est une bibliothèque de classes...
    Certaines wrappent des fonctions classiques telles les expressions régulières.
  • AliGatorAliGator Membre, Modérateur
    mai 2007 modifié #5
    Je ne connaissais pas MOKit, mais en tant que fana des expressions régulières (RegEx  pour les intimes :P), je sens que je vais m'y essayer :)

    D'accord avec schlum pour l'inversion de la greedyness des quantificateurs, un "?" pour l'inverser.
    Mais ce qui est étrange c'est qu'on ne puisse pas changer ces flags directement dans la classe MORegularExpression  ???.

    En PHP tu peux mettre ces flags (genre "U" pour "ungreedy", "non-gourmand") à  la fin de ta RegEx car celle-ci est entourée de délimiteurs ; tu mets alors tes flags après le délimiteur fermant, genre "/maregex/U". Mais là  tu ne spécifies que la regex, donc s'il y avait la possibilité de mettre des flags, ce serait dans un autre paramètre du selecteur... comme c'est le cas pour [tt]ignoreCase:[/tt] apparament

    Je ne connais pas MOKit ni n'ait sa doc sous les yeux, mais n'y aurait-il donc pas une autre méthode qui, en plus de prendre la regex, permettrait de spécifier la greedyness (comme le "ignoreCase:" que tu as mis dans ton code ?) ou un setter genre "setGreedyness:(BOOL)isGreedy" pour spécifier le mode gourmand ou non ?

    Ceci pour éviter de modifier la gourmandise des quantificateurs de manière unitaire sur chacun, mais le faire de manière globale... Maintenant j'imagine que si tu poses la question c'est que tu n'as pas trouvé dans la doc (mais je pose qd mm la question car tout le monde ne sait pas que cela s'appelle la "gourmandise" ou "greedyness" des quantificateurs, donc ça peut t'aider à  chercher dans la doc), et s'il n'y a rien d'autre, la modification de chaque quatificateur (avec un "?" derrière comme t'a indiqué schlum) sera alors la seule solution ;)
  • schlumschlum Membre
    09:17 modifié #6
    J'ai un peu fouillé les sources pour voir justement ces options, et apparemment c'est une sorte de Wrapper sur les fonctions standard "regcomp", "regexec", "regerror" et "regfree" de la librairie standard C (regex.h) (je m'en doutais à  vrai dire, car il n'y a pas grand chose de plus haut niveau en C / C++ ; ceci-dit, ça aurait pu wrapper du PERL)

    Je ne crois pas que les options de ces fonctions permettent de gérer la gourmandise globale de l'expression...

    D'après le man, les options sont :

         REG_EXTENDED  Compile modern (``extended&#39;&#39;) REs, rather than the obsolete<br />                   (``basic&#39;&#39;) REs that are the default.<br /><br />     REG_BASIC     This is a synonym for 0, provided as a counterpart to<br />                   REG_EXTENDED to improve readability.<br /><br />     REG_NOSPEC    Compile with recognition of all special characters turned<br />                   off.  All characters are thus considered ordinary, so the<br />                   ``RE&#39;&#39; is a literal string.  This is an extension, compati-<br />                   ble with but not specified by IEEE Std 1003.2<br />                   (``POSIX.2&#39;&#39;), and should be used with caution in software<br />                   intended to be portable to other systems.  REG_EXTENDED and<br />                   REG_NOSPEC may not be used in the same call to regcomp().<br /><br />     REG_ICASE     Compile for matching that ignores upper/lower case distinc-<br />                   tions.  See re_format(7).<br /><br />     REG_NOSUB     Compile for matching that need only report success or fail-<br />                   ure, not what was matched.<br /><br />     REG_NEWLINE   Compile for newline-sensitive matching.  By default, new-<br />                   line is a completely ordinary character with no special<br />                   meaning in either REs or strings.  With this flag, `[^&#39;<br />                   bracket expressions and `.&#39; never match newline, a `^&#39;<br />                   anchor matches the null string after any newline in the<br />                   string in addition to its normal function, and the `$&#39;<br />                   anchor matches the null string before any newline in the<br />                   string in addition to its normal function.<br /><br />     REG_PEND      The regular expression ends, not at the first NUL, but just<br />                   before the character pointed to by the re_endp member of<br />                   the structure pointed to by preg.  The re_endp member is of<br />                   type const char *.  This flag permits inclusion of NULs in<br />                   the RE; they are considered ordinary characters.  This is<br />                   an extension, compatible with but not specified by IEEE Std<br />                   1003.2 (``POSIX.2&#39;&#39;), and should be used with caution in<br />                   software intended to be portable to other systems.
    
  • TchouboudouTchouboudou Membre
    09:17 modifié #7
    Maintenant, j'ai ce code:
    NSString *inHTML = @&quot;&lt;gras&gt;blo&lt;/gras&gt;&#092;n&lt;gras&gt;Test&lt;/gras&gt;&quot;;<br />	<br />	MORegularExpression *bothExp = [MORegularExpresssion regularExpressionWithString:@&quot;&lt;gras&gt;(.+?)&lt;/gras&gt;&quot; ignoreCase:YES];<br />	<br />	NSArray *array = [bothExp subexpressionsForString:inHTML];<br />	<br />	NSENumerator *e = [array objectEnumerator];<br />	NSString *tmp;<br />	<br />	while (tmp = [e nextObject]) NSLog(@&quot;%@&quot;, tmp);
    


    Et j'obtiens :

    2007-05-18 15:59:55.612 MOKitTest[619] <gras>blo</gras>
    2007-05-18 15:59:55.643 MOKitTest[619] blo


    Il y a donc une balise en moins.
    Donc, la solution proposé par Schlum, qui est de mettre une options, comment se fait-elle ?

    Sinon, il y a un autre framework, OgreKit. Vous savez des choses dessus ?

    Merci d'avance,
    Tchouboudou

    PS : j'ai pas trouvé de doc sur le site de MOKit...
  • AliGatorAliGator Membre, Modérateur
    09:17 modifié #8
    Ca n'a pas l'air si simple en effet...

    En fait apparament il faut utiliser [tt]substringForSubexpressionAtIntex:idx[/tt] pour avoir le match n°idx (qui te renverra une substring vide s'il ne la trouve pas, si j'ai tout suivi).

    Voir ici quelques détails

    Quitte à  faire un wrappeur, ils auraient pu faire qqch de plus simple ;)
  • TchouboudouTchouboudou Membre
    09:17 modifié #9
    Merci de ces réponses, mais, en fait, je vais utiliser OgreKit, j'arrive à  la faire marcher :) .
  • 09:17 modifié #10
    Sinon je viens de découvrir une "bibliothèque" beaucoup plus simple que l'OgreKit:
    http://aarone.org/cocoaicu/
  • TchouboudouTchouboudou Membre
    09:17 modifié #11
    Merci pour le lien Renaud, il me semble que c'est la librairie utilisé par Smultron.

    Hors-sujet :

    Comment on télécharge en SVN  :-\\
  • 09:17 modifié #12
    Tu tapes la commande indiquée sur la page dans le terminal, tout simplement.

    Sinon quand tu regardes l'adresses dans la commande, tu as souvent svn:// ou http:// comme service. Si c'est http://, tu peux aller dans le Finder -> Aller -> Se connecter au serveur et tu tapes là  l'adresse.
  • TchouboudouTchouboudou Membre
    09:17 modifié #13
    C'est bon, merci :)
  • TchouboudouTchouboudou Membre
    09:17 modifié #14
    J'ai un petit problème pour l'installation de ICU. À partir du numéro 3 (comme je suis gentil, j'ai fait un copié-collé) :

    Add the directory icu (included in the CocoaICU distribution) to the Header Search Path of your project.

    Une question se pose dans ma tête : "Qu'est-ce c'est le Header Search Path ?"

    *Vous m'excuserez de ne pas créer de nouveau sujet, c'est dans la continuité ::)*
  • 09:17 modifié #15
    Clique sur l'icône du projet dans la liste latérale, ouvre l'inspecteur et dans l'onglet "Build" il y a une ligne nommée "Headers search paths".
Connectez-vous ou Inscrivez-vous pour répondre.