以下のようなステートメントを効果的に解析する方法 (コードが乱雑にならないようにする方法)。キーワード/セパレーターは [] 内に配置されます。
Manager, Delhi [for] The Company Pvt Ltd. [from] 2009 年 1 月 [to] 2012 年 1 月。
構文解析コンビネータを使用して、テキストから人名、会社名、および日付範囲を抽出します。(期待される出力は下部に表示されます)
以下は、上記のために書かれたコードです-
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)
}
}
}
出力は次のようになります
CompanyWithMonthDateRange(List(((()~Company)~List()), ((()~fd)~List()), ((()~India)~List('))),(()~Manager, ),(()~Delhi ),List(MonthYear(mar,2010), MonthYear(jul,2012)))
また、上記のテキストに表示される不要な「〜」を削除する方法。
ありがとう、パワン