2012-04-25 4 views
0

아래와 같이 구문을 효과적으로 구문 분석하는 방법은 무엇입니까? 키워드/구분 기호는 [] 안에 있습니다.파서 - 결합자를 사용하여 스칼라 문장을 구문 분석

관리자, 델리 [대한] 회사 Pvt 주식 회사는 월 2009 [에서] 월, 사람의 2012 년

이름 [에], 회사 명 및 날짜 범위는 사용하여 텍스트 분석에서 추출 할 수 있습니다 연결자. 원치 않는를 제거하는 방법 또한



    CompanyWithMonthDateRange(List(((()~Company)~List()), ((()~fd)~List()), ((()~India)~List('))),(()~Manager,),(()~Delhi),List(MonthYear(mar,2010), MonthYear(jul,2012))) 

같은 아래

는 전술



    case class CompanyWithMonthDateRange(company:String, position:String, dateRange:List[MonthYear]) 

    case class MonthYear(month:String, year:Int) 

    object CompanyParser1 extends RegexParsers { 
     override type Elem = Char 
     override def skipWhitespace = false 
     def keywords: Parser[String] = "for" | "in" | "with" |"at" | "from" | "pvt"|"ltd" | "company" | "co" | "limited" | "inc" | "corporation" | "jan" |\ 
    "feb" | "mar" | "apr" | "may" | "jun" | "jul" | "aug" | "sep" | "nov" | "dec" | "to" | "till" | "until" | "upto" 

     val date = ("""\d\d\d\d""".r | """\d\d""".r) 
     val integer  = ("""(0|[1-9]\d*)""".r) ^^ { _.toInt } 
     val comma = ("""\,""".r) 
     val quote = ("""[\'\"]+""".r) 
     val underscore = ("""\_""".r) 
     val dot = ("""\.""".r) 
     val space = ("""\s+""".r) ^^ {case _ => ""} 
     val colon = (""":""".r) 
     val ampersand = ("""(\&|and)""".r) 
     val hyphen = ("""\-""".r) 
     val brackets = ("""[\(\)]+""".r) 
     val newline = ("""[\n\r]""".r) 
     val months = ("""(jan|feb|mar|apr|may|jun|jul|aug|sep|nov|dec)""".r) 
     val toTillUntil = ("""(to|till|until|upto)""".r) 
     val asWord = ("""(as)""".r) 
     val fromWord = ("""from""".r) 
     val forWithAt = ("""(in|for|with|at)""".r) 
     val companyExt = ("""(pvt|ltd|company|co|limited|inc|corporation)""".r) 
     val alphabets = not(keywords)~"""[a-zA-Z]+""".r 
     val name = not(keywords)~"""[a-zA-Z][a-zA-Z\,\-\'\&\(\)]+\s+""".r 

     def possibleCompanyExts = companyExt <~ (dot *) ^^ {_.toString.trim} 
     def alphabetsExt = ((alphabets ~ ((quote | ampersand | hyphen | brackets | underscore | comma) *) <~ (space *))+) ^^ { case a => a.toString.trim} 
     def companyNameExt = (alphabetsExt <~ (space *) <~ (possibleCompanyExts+)) ^^ {_.toString 
     } 
     def companyName = alphabetsExt * 
     def entityName = (alphabetsExt+) ^^ {case l => l.map(s => s.trim).mkString(" ")} 
     def dateWithEndingChars = date <~ ((comma | quote | dot | newline) *) <~ (space *) ^^ {_.toInt} 
     def monthWithEndingChars = months <~ ((comma | quote | dot | newline) *) <~ (space *) ^^ { _.toString} 
     def monthWithDate = monthWithEndingChars ~ dateWithEndingChars ^^ { case a~b => MonthYear(a,b)} 
     def monthDateRange = monthWithDate ~ (space *) ~ toTillUntil ~ (space *) ~ monthWithDate ^^ { case a~s1~b~s2~c => List(a,c)} 
     def companyWithMonthDateRange = (companyNameExt ~ (space *) ~ monthDateRange) ^^ { 
     case a~b~c => CompanyWithMonthDateRange(company = a, dateRange = c, position = "") 
     } 
     def positionWithCompanyWithMonthDateRange = ((name+) ~ (space *) ~ forWithAt ~ (space *) ~ companyWithMonthDateRange) ^^ {    
     case a~s1~b~s2~c => c.copy(position = a.mkString(",")) 

     } 
    def apply(input:String) =  { 
     parseAll(positionWithCompanyWithMonthDateRange,input) match { 
     case Success(lup,_) => println(lup) 
     case x => println(x) 
     } 
     } 
    } 

출력을 위해 작성된 코드입니다 (예상 출력이 하단에 표시)해야 뭔가 "~" 위의 텍스트에 나타납니다.

감사합니다, Pawan

답변

0

난 그냥 당신이 제공 한 데이터 구조로 문장을 구문 분석, 실제 문제에 대한 완벽한 솔루션으로이 작성하려고 아니에요, 내가 잘 모르겠어요 참조로 도움이됩니다.

귀하의 CompanyWithMonthDateRange에는 추출한 이름을 어디에 넣어야하는지 알지 못했기 때문에이를 생략하고 추가하겠습니다.

object TestP extends App { 
    val inStr1 = """ 
    Manager, Delhi [for] The Company Pvt Ltd. [from] Jan, 2009 [to] Jan, 2012. 
    """ 
    val inStr2 = """ 
    Manager, Delhi [for] The Company Pvt Ltd. [from] Jan, 2009 [to] Jan, 2012. 
    Employee, Kate [for] The Company Pvt Ltd. [from] Feb, 2010 [to] Jun, 2012. 
    HR, Jane  [for] The Company Pvt Ltd. [from] May, 2010 [to] July, 2012. 
    """ 
    CompParser(inStr1) 
    CompParser(inStr2) 
} 

출력은 다음과 같습니다 : inStr1 :

목록 (일부 (CompanyWithMonthDateRange (회사

object CompParser extends RegexParsers { 
    val For = "[for]" 
    val From = "[from]" 
    val To = "[to]" 
    val Keyword = For | From | To 
    val Def = """(?m)(?<=^|\]).*?(?=\[|(\.\s*[\n\r]+))""".r 
    val End = """.""".r 
    val Construct = opt(Def) ~ Keyword ~ Def ^^ { 
    case p ~ `For` ~ s => { 
     val arr = p.getOrElse("").split(",") 
     val t2 = if (arr.length == 2) arr(0) -> arr(1) else ("", "") 
     ("pos&com", (t2._1, s.toString)) 
    } 
    case p ~ `From` ~ s => { 
     val arr = s split "," 
     val t2 = if (arr.length == 2) arr(0) -> arr(1) else ("", "") 
     ("from", (t2._1, t2._2)) 
    } 
    case p ~ `To` ~ s => { 
     val arr = s split "," 
     val t2 = if (arr.length == 2) arr(0) -> arr(1) else ("", "") 
     ("to", (t2._1, t2._2)) 
    } 
    } 
    val Statement = rep(Construct) ^^ (Map() ++ _) ^^ { m => 
    if (m.size == 3) { 
     val from = new MonthYear(m.get("from").head._1, m.get("from").head._2.trim.toInt) 
     val to = new MonthYear(m.get("to").head._1, m.get("to").head._2.trim.toInt) 
     val pos = m.get("pos&com").head._1 
     val com = m.get("pos&com").head._2 
     new Some(CompanyWithMonthDateRange(com, pos, List(from, to))) 
    } else None 
    } 

    val Statements = rep(Statement <~ End) 

    def apply(in: String) = { 
    parseAll(Statements, in) match { 
     case Success(r, i) => println(r) 
     case failure => failure 
    } 
    } 
} 

및 파서가 줄 바꿈에 정차, 여기에 파서에 대한 테스트입니다 Pvt Ltd. , 관리자 (MonthYear (Jan, 2009), MonthYear (Jan, 2012))))))))))

inStr2 :

목록 (일부 (CompanyWithMonthDateRange (회사 Pvt 주식 회사 , 관리자 일부 (CompanyWithMonthDateRange, 목록 (MonthYear (월, 2009), MonthYear (월, 2012)))), ((CompanyWithMonthDateRange (회사 Pvt Ltd. , HR, List (MonthYear (2010 년 5 월)), 일부 회사는 (회사의 Pvt 주식 회사 직원, , MonthYear (July, 2012)))))

관련 문제