1

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 printlns 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.*")
0

1 Answer 1

2

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.

Sign up to request clarification or add additional context in comments.

7 Comments

Have a look at this demo. __HS512__ does not show .*HS512.*, it shows all 3 regexps, and then an exception is thrown, too. Do you know why?
Boom! This solves it. There was zero chance I could have found the answer on my own. Kudos.
Well, you could just make the argument optional (.r(_*)) - you would get the same behavior.
@WiktorStribiżew The code you've shown does not throw an exception. All three regexps are printed because the HS512 comes last, so all three need to be tried (and therefore constructed).
Yes, I tried many variations, and in some of them I had the exception thrown, too. I just wonder if all of them really should be printed. I felt OP needed just the matching object.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.