Reputation: 6188
I have a ADT representing the crypto algorithms I want to use/detect. The generic class Algo contains some utility methods, including a handy auto-generated regex useful to detect the name of the algo inside a string.
sealed trait Algo {
override def toString = this.getClass.getSimpleName.dropRight(1)
val name = toString
val javaName = toString.replaceFirst("HS", "HmacSHA")
val r = s".*$name.*".r
println(r)
}
case object HS256 extends Algo
case object HS348 extends Algo
case object HS512 extends Algo
val someString = "__HS256__"
val result = someString match {
case HS256.r(_) => HS256
case HS348.r(_) => HS348
case HS512.r(_) => HS512
case _ => throw new Exception("Algorithm can't be matched")
}
The above prints (see the println
s in the trait constructor) the regexes how I expect them to look like, that is:
.*HS256.*
.*HS348.*
.*HS512.*
But none match and the program throws the exception instead of matching HS256
. Why does this happen, since this apparently equivalent line works well:
"__HS256__".matches(".*HS256.*")
Upvotes: 1
Views: 77
Reputation: 370435
The pattern r(p)
, where r
is a regex and p
is another pattern, matches a given string if that string matches the regex and the pattern p
matches the first capturing group of the regex match. Since your regex does not have any capturing groups, no pattern will match the first capturing group, not even the pattern _
.
To make the match work, use the pattern r()
, which does not try to match any capturing groups, or r(_*)
, which matches regardless of how many groups the regex has.
Upvotes: 2