11
votes

Accéder aux données d'expression régulières d'une parsière SCALA

Je me demande s'il est possible d'obtenir le matchdata généré à partir de l'expression régulière correspondante dans la grammaire ci-dessous.

object DateParser extends JavaTokenParsers {

    ....

    val dateLiteral = """(\d{4}[-/])?(\d\d[-/])?(\d\d)""".r ^^ {
        ... get MatchData
    }
}


0 commentaires

4 Réponses :


1
votes

Lorsqu'une regex est utilisée dans une instance REGEXPARSERSERSERS, la Implicit Implicit Def Regex (regex): analyse [String] dans RegExparsers est utilisé pour appuyer sur ce regex à l'entrée. L'instance de correspondance a donné une application réussie de la Re à l'entrée actuelle est utilisée pour construire un succès dans la méthode Regex (), mais seule sa valeur «fin» est utilisée, de sorte que tout sous-correspondant capturé est rejeté au moment de la méthode de cette méthode. retourne.

Comme il se trouve (dans la source 2.7 que j'ai regardé), vous n'avez pas de chance, je crois.


0 commentaires

3
votes

Non, vous ne pouvez pas faire cela. Si vous regardez la définition de l'analyseur utilisé lorsque vous convertissez une regex à un analyseur, il lance tout contexte et renvoie simplement la chaîne correspondante complète:

http://lamamsvn.epfl.ch /trac/scala/browser/scala/tags/r_2_7_7_final/src/library/scala/util/parsing/combinator/regexparsers.scala?view=markup#l55

Vous avez deux Autres options, cependant:

  • rompre votre analyseur en plusieurs petits analyseurs (pour les jetons que vous souhaitez réellement extraire)
  • Définissez un analyseur personnalisé qui extrait les valeurs que vous souhaitez et renvoie un objet de domaine au lieu d'une chaîne

    le premier ressemblerait à xxx

    le <~ signifie "nécessite ces deux jetons ensemble, mais ne me donnez que le Résultat du premier.

    Le ~ signifie "nécessite ces deux jetons ensemble et les attache ensemble dans un objet fixable par motif.

    < code>? signifie que l'analyseur est facultatif et retournera une option.

    Le bit .getorelse offre une valeur par défaut pour le moment où l'analyseur n'a pas défini un valeur.


2 commentaires

Merci David, belle solution. Je vais aller avec la solution d'analyse personnalisée car elle maintient la définition de la grammaire plus lisible.


Maintenant que j'y pense, un analyseur personnalisé est également plus correct. Chaque analgésique de Regex autorise la tête de l'espace de tête, de sorte que le code que j'ai affiché correspondrait également aux chaînes telles que "1999 - 02 - 28".



20
votes

Voici la définition implicite qui convertit votre regex dans un parser : xxx

il suffit de l'adapter: < Pré> xxx

exemple: xxx


3 commentaires

C'est étrangement pourquoi une telle sorte de fonctionnalité ne fait pas partie de la mise en œuvre de la classe standard (Bibliothèque)? Il semble assez utile, mais chaque utilisateur doit la mettre en œuvre par soi ...


@DMitryBespalov On peut simplement appliquer le motif à nouveau pour extraire des groupes et utiliser plutôt une grammaire que des règles de regex plus complexes. Donc, oui, cela pourrait être utile, mais ce n'est pas nécessaire, et il y a de graves inconvénients dans une bibliothèque gonflée.


On sait que Lexing est plus efficace avec une regex avec une analyse conventionnelle. Entre-temps, Lexer avec RegureParsers donne Object Lexer hérite de type membre conflictuel ELEM dans des scanners de trait et des refroidisseurs et je ne peux pas ne pas étendre les réégyts car il définit la fonction manuiste .



0
votes

J'ai couru dans un problème similaire à l'aide de Scala 2.8.1 et essaye d'analyser l'entrée du formulaire "Nom: Valeur" à l'aide de la catégorie code> Regexparsers Code> Classe:

QueryParser.parseItem("nameExample:valueExample") match {
  case QueryParser.Success(result:scala.util.parsing.combinator.Parsers$$tilde, _) => {
      println("Name: " + result.productElement(0) + " value: " + result.productElement(1))
  }
}


0 commentaires