這適用於你的特殊情況:
scala> val InputPattern = "(put) (.*?) ?(in) ?(.*?)".r
InputPattern: scala.util.matching.Regex = (put) (.*) ?(in) ?(.*)
scala> val InputPattern(verb, item, prep, obj) = "put a in b"
verb: String = put
item: String = a
prep: String = in
obj: String = b
scala> val InputPattern(verb, item, prep, obj) = "put in"
verb: String = put
item: String = ""
prep: String = in
obj: String = ""
put
和in
這裏在團體參與模式匹配還抓獲。我也用懶惰正則表達式(.*?)
儘可能少的捕獲,你可以用(\S*)
替換它。 ?
爲您提供了可選空間,以匹配 「放入」(put
和in
之間的一個空格,並且末尾沒有空格)。
但要注意的是:
scala> val InputPattern(verb, item, prep, obj) = "put ainb"
verb: String = put
item: String = a
prep: String = in
obj: String = b
scala> val InputPattern(verb, item, prep, obj) = "put aininb"
verb: String = put
item: String = a
prep: String = in
obj: String = inb
scala> val InputPattern(verb, item, prep, obj) = "put ain"
verb: String = put
item: String = a
prep: String = in
obj: String = ""
如果你有簡單的命令解釋器可能就算不錯了,否則你應分別符合您的特殊情況。
要處理一個簡單的(不自然)語言,你也可以考慮StandardTokenParsers
,因爲它們是上下文無關(Chomsky type 2):
import scala.util.parsing.combinator.syntactical._
val p = new StandardTokenParsers {
lexical.reserved ++= List("put", "in")
def p = "put" ~ opt(ident) ~ "in" ~ opt(ident)
}
scala> p.p(new p.lexical.Scanner("put a in b"))
warning: there was one feature warning; re-run with -feature for details
res13 = [1.11] parsed: (((put~Some(a))~in)~Some(b))
scala> p.p(new p.lexical.Scanner("put in"))
warning: there was one feature warning; re-run with -feature for details
res14 = [1.7] parsed: (((put~None)~in)~None)
我猜你需要用4個捕獲組,例如模式'(M)^(\ S *)\ S *(\ S *?)\ S *(\ S *)\ S *(\ S *?)$'。看看演示:https://regex101.com/r/mC5eI5/1 –