Это работает для особых случаев:
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 –