2016-03-29 13 views
2

Ich schreibe einen Lexer/Scanner zum ersten Mal, und habe ein Problem beim Aufteilen der Eingabezeichenkette gehabt. Beispiel:Wie man eine Zeichenkette auf mehrfachen regulären Ausdrücken teilt, während man die aufspaltenden Zeichen behält

val result = "func add(Num x, Num y) = x+y;".split(???) 
result == Array("func", "add", "(", "Num", "x", ",", "Num", "y", ")", "=", "x", "+", "y", ";") 

Aber das Problem ist, dass ich nicht einfach auf Leerzeichen aufteilen, also nicht add von ( zum Beispiel trennen würde tun.

Irgendwelche Hilfe dabei?

+0

nicht * sprechen * scala;), so kann ich Ihnen nicht sagen, wie man mit den leeren Einträgen umgeht, aber auf '\ s | \ b' spaltet - Wortgrenzen hinzufügen - sollte es tun. Siehe [regex101 Beispiel] (https://regex101.com/r/lB7sB3/2) – ClasG

+1

@ClasG, das den Trick gemacht hat, wenn Sie es als eine Antwort posten Ich werde es akzeptieren – Saveyy

Antwort

1

Dies wird Ihnen eine Reihe von leeren Elementen, die Ihre EE zu behandeln haben, aber Hinzufügen von Word-Grenze - \b - sollte es tun.

Überprüfen Sie example at regex101.

I.e. ...split('\s|\b') (oder /\s|\b/).

Grüße

+0

Wenn ich nicht falsch liege, wird dies hinzufügen Leerzeichen im Ergebnis, die ich denke, ist nicht die erwartete –

0

Blick in http://www.scala-lang.org/api/rc/index.html#scala.util.parsing.combinator.RegexParsers

Hier ist ein unfertiges Beispiel:

import scala.util.parsing.combinator.RegexParsers 

trait Element 

case class Function(name: String, 
                    params:Map[String, String], 
                    expression:Seq[String]) extends Element 

case class Class(name: String, 
                 params: Map[String,String], 
                 body: Seq[String]) extends Element 

object LanguageParser extends RegexParsers { 

  val name: Parser[String] = ".*".r 

  val `type`: Parser[String] = ??? 

  val parameters: Parser[Map[String,String]] = "(" ~> (`type` ~ name).* <~")" ^^ { 
    case t => (t map { 
      case a ~ b => a -> b 
    }).toMap 
  } 

  val expression: Parser[Seq[String]] = ??? 

  val function: Parser[Function] = 
    "func " ~> name ~ parameters ~ "="~ expression ^^ { 
      case name ~  params ~ _ ~ expr => Function(name, params, expr) 
    } 
   
  val `class`: Parser[Class] = 
    "class " ~> name ~ parameters ~ "{" ~ expression ~ "}" ^^ { 
      case name ~  params ~ _ ~ expr ~_ => Class(name, params, expr) 
    } 

  val topLevelParsers: Parser[Seq[Element]] = 
    function | 
      `class` | 
      value | 
      ifelse 

  def parse(s: String): Seq[Element] = parseAll(topLevelParsers, s.trim) getOrElse 
    (throw newIllegalArgumentException("Could not parse the given string: " + s.trim)) 

  def parseAll(s: String):Seq[Element] = 
    s split ";" flatMap parse 
} 

Prost

+0

Für jetzt ist das \ b | \ s ausreichend. aber ich fürchte, ich müsste den Code, den ich habe, neu schreiben und über den Regex-Parser lernen, um eine zuverlässigere Lösung zu erreichen. Danke für deine Antwort ! – Saveyy

+0

Sie sparen Zeit beim Lernen. Ich habe nicht das erste Mal, weil ich faul war, ich musste alles umschreiben und immer wieder sagen, warum ich das vorher nicht wusste. – Joan