I am trying to parse an expression with (<, <=, >=, >). All but <= works just fine. Can someone help what could be the issue. Code:
我试图用(<,<=,> =,>)解析表达式。除<=之外的所有工作都很好。有人可以帮助解决问题。码:
object MyTestParser extends RegexParsers {
override def skipWhitespace = true
private val expression: Parser[String] = """[a-zA-Z0-9\.]+""".r
val operation: Parser[Try[Boolean]] =
expression ~ ("<" | "<=" | ">=" | ">") ~ expression ^^ {
case v1 ~ op ~ v2 => for {
a <- Try(v1.toDouble)
b <- Try(v2.toDouble)
} yield op match {
case "<" => a < b
case "<=" => a <= b
case ">" => a > b
case ">=" => a >= b
}
}
}
Test:
测试:
"MyTestParser" should {
"successfully parse <= condition" in {
val parser = MyTestParser.parseAll(MyTestParser.operation, "10 <= 20")
val result = parser match {
case MyTestParser.Success(s, _) => s.get
case MyTestParser.Failure(e, _) =>
println(s"Parsing failed with error: $e")
false
case MyTestParser.Error(e, _) =>
println(s"Parsing error: $e")
false
}
result === true
}
"successfully parse >= condition" in {
val result = MyTestParser.parseAll(MyTestParser.operation, "50 >= 20").get
result === scala.util.Success(true)
}
}
Error for <= condition:
<=条件的错误:
Parsing failed with error: string matching regex `[a-zA-Z0-9\.]+' expected but `=' found
3 个解决方案
#1
2
You need to change the order of the alternatives so that the longest options could be checked first.
您需要更改备选项的顺序,以便可以首先检查最长的选项。
expression ~ ( "<=" | ">=" | ">" | "<") ~ expression ^^ {
If the shortest alternative matches first, others are not considered at all.
如果最短的替代方案首先匹配,则根本不考虑其他方案。
Also note that a period does not have to be escaped inside a character class, this will do:
另请注意,句点不必在字符类中进行转义,这样做:
"""[a-zA-Z0-9.]+""".r
#2
2
Your problem is that "<" is matched by <=, so it moves on to trying the expression. If you change the order so that "<=" comes first, that will be matched instead, and you will get the desired result.
您的问题是“<”与<=匹配,因此它继续尝试表达式。如果您更改顺序以便首先出现“<=”,那么将匹配,您将获得所需的结果。
#3
2
@Prateek: it does not work cause the regex engine works just like a boolean OR. It does not search further if one of the patterns in the or-chain is satisfied at a certain point.
@Prateek:它不起作用,因为正则表达式引擎就像布尔OR一样工作。如果在某个点满足or链中的一个模式,则不会进一步搜索。
So, when use |
between patterns, if two or more patterns have substring in common, you have to place the longest first.
所以,当使用|在模式之间,如果两个或多个模式具有共同的子字符串,则必须先放置最长的模式。
As a general rule: order the patterns starting from the longest to the shortest.
作为一般规则:从最长到最短的顺序排列模式。
Change the relevant line like this make it works:
像这样更改相关行使其工作:
// It works as expected with '>= / >' also before for the same reason
expression ~ ("<=" | "<" | ">=" | ">") ~ expression ^^ {
Or you want to follow the general rule:
或者你想遵循一般规则:
expression ~ ("<=" | ">=" | "<" | ">") ~ expression ^^ {
#1
2
You need to change the order of the alternatives so that the longest options could be checked first.
您需要更改备选项的顺序,以便可以首先检查最长的选项。
expression ~ ( "<=" | ">=" | ">" | "<") ~ expression ^^ {
If the shortest alternative matches first, others are not considered at all.
如果最短的替代方案首先匹配,则根本不考虑其他方案。
Also note that a period does not have to be escaped inside a character class, this will do:
另请注意,句点不必在字符类中进行转义,这样做:
"""[a-zA-Z0-9.]+""".r
#2
2
Your problem is that "<" is matched by <=, so it moves on to trying the expression. If you change the order so that "<=" comes first, that will be matched instead, and you will get the desired result.
您的问题是“<”与<=匹配,因此它继续尝试表达式。如果您更改顺序以便首先出现“<=”,那么将匹配,您将获得所需的结果。
#3
2
@Prateek: it does not work cause the regex engine works just like a boolean OR. It does not search further if one of the patterns in the or-chain is satisfied at a certain point.
@Prateek:它不起作用,因为正则表达式引擎就像布尔OR一样工作。如果在某个点满足or链中的一个模式,则不会进一步搜索。
So, when use |
between patterns, if two or more patterns have substring in common, you have to place the longest first.
所以,当使用|在模式之间,如果两个或多个模式具有共同的子字符串,则必须先放置最长的模式。
As a general rule: order the patterns starting from the longest to the shortest.
作为一般规则:从最长到最短的顺序排列模式。
Change the relevant line like this make it works:
像这样更改相关行使其工作:
// It works as expected with '>= / >' also before for the same reason
expression ~ ("<=" | "<" | ">=" | ">") ~ expression ^^ {
Or you want to follow the general rule:
或者你想遵循一般规则:
expression ~ ("<=" | ">=" | "<" | ">") ~ expression ^^ {