[英]Scala Regex Pattern Matching
我需要使用正则表达式来匹配Scala中的模式,并且我目前有一个正则表达式
InputPattern: scala.util.matching.Regex = put (.*) in (.*)
当我执行以下操作时:
scala> val InputPattern(verb, item, prep, obj) = "put a in b";
scala.MatchError: put a in b (of class java.lang.String)
... 33 elided
我希望以输入( put a in b)和verb("put"), item(""), prep("in"), and obj("")
verb("put"), item("a"), prep("in"), and obj("b")
输入的verb("put"), item("a"), prep("in"), and obj("b")
结尾输入的“ put in”的 verb("put"), item(""), prep("in"), and obj("")
。
谢谢
您可以为所有情况编写一个正则表达式,但是我不确定它是否可读和可维护。 我更喜欢简单的方法:
val pattern1 = "(put) (.*) (in) (.*)".r
val pattern2 = "(put) (in)".r
def parse(text: String) = text match {
case pattern1(verb, item, prep, obj) => (verb, item, prep, obj);
case pattern2(verb, prep) => (verb, "", prep, "")
}
scala> parse("put a in b")
res6: (String, String, String, String) = (put,a,in,b)
scala> parse("put in")
res7: (String, String, String, String) = (put,"",in,"")
还有一个想法:希望您知道自己在做什么! RegEx是Chomsky Type 3语法 ,自然语言要复杂得多。 如果需要自然语言解析器,则可以使用已有的解决方案,例如Stanford NLP解析器 。
这适用于您的特殊情况:
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类型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)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.