2015-01-13 2 views
0

입력 내용 중 일부는 다음과 같습니다.스칼라 파서 결합 자의 Java 정규식

Name 
John Doe 
Sons 
Name 
Son of John 
28 
: 
Name 
Jane Doe 
Daughters 
Name 
Daughter of Jane 
32 
... 
... 

내 파서는이

rep("Name" ~> rep("[A-Z ]+[a-z ]+".r) ~> ("Sons Name" | "Daughters Name") ~> "[0-9]+") 

처럼 보이는뿐만 아니라 멀리 Name, Daughter of Jane 다음과 같은 오류가 발생 Son of John 취 정규식 rep("[A-Z ]+[a-z ]+".r)과 같습니다

failure: `Daughters ' expected but `2' found 

궁금 인을 이 문제를 해결할 수있는 간단한 방법이 있습니까?

+0

주어진 예제에서 예상되는 구문 분석 결과가'List (28, 32)'가되도록 파서가 각 사람마다 일치하는 숫자 (각 사람의 나이라고 가정)를 반환하도록 하시겠습니까? ? – edi

+0

파서가'Name','Daughter/Son Name'과'age'를 반환하기를 바랍니다. –

답변

1

저는 파서를 조금 변형하여 정규 표현식 중 일부를 더 명확하게했습니다. 또한, skipWhitespacefalse으로 설정 했으므로 일치하는 부분보다 세밀하게 제어 할 수 있습니다. 나는 이것이 당신의 문제를 다루기위한 가장 관용적 인 접근법인지는 모르지만 그것은 효과적입니다. 희망이 도움이됩니다.

import scala.util.parsing.combinator._ 

object Parser extends RegexParsers { 

    override val skipWhitespace = false 

    val word = """[A-Za-z]+""".r 
    val separator = """\s+""".r  
    val colon = """(\s+:\s+)?""".r // optional colon 
    val ws = """[^\S\n]+""".r  // all whitespace except newline 
    val age = "[0-9]+".r 

    val name = (repsep(word, ws) <~ separator) ^^ (_.mkString(" ")) 
    val nameHeader = "Name" ~ separator 
    val childNameHeader = ("Daughters" | "Sons") ~ separator ~ nameHeader 

    val person = nameHeader ~> name ~ (childNameHeader ~> name) ~ age <~ colon ^^ (p => (p._1._1, p._1._2, p._2)) 
    val persons = rep(person) 

} 

object Main extends App { 

    val input = 
    """Name 
     |John Doe 
     |Sons 
     |Name 
     |Son of John 
     |28 
     |: 
     |Name 
     |Jane Doe 
     |Daughters 
     |Name 
     |Daughter of Jane 
     |32""".stripMargin 

    val result = Parser.parse(Parser.persons, input) 
    // prints '[13.3] parsed: List((John Doe,Son of John,28), (Jane Doe,Daughter of Jane,32))' 
    println(result) 
}