Rafa
Rafa

Reputation: 3339

Pattern match an array of Regex's in Scala

I have an array of regex's in Scala, and am trying to verify that a message body contains anything in the regex. However, in the messageBody variable I'm getting a Pattern type is incompatible with given type, expected Array[Regex], found Array[String]. How can I pass in a proper case?

A few other posts have suggested using Pattern but that hasn't worked in my case.

  val messageBody: Array[String] = message.body.split(' ')
  val unsubscribeTriggers: Array[Regex] = Array("unsubscribe/i".r, "stop/i".r, "stopall/i".r, "cancel/i".r, "end/i".r, "quit/i".r)\

  if (messageBody.length == 1) {
        unsubscribeTriggers match {
          case `messageBody` => true

          case _ => false

        }
}

Upvotes: 0

Views: 1075

Answers (3)

Steven Wexler
Steven Wexler

Reputation: 17269

You can match on regex individual variables pretty cleanly also.

val messageBody: Array[String] = message.body.split(' ')

val unsubscribe = "(?i)unsubscribe".r
val stop = "(?i)stop".r
val stopall = "(?i)stopall".r
val cancel = "(?i)cancel".r
val end = "(?i)end".r
val quit = "(?i)quit".r

val shouldUnsubscribe = messageBody.headOption.exists {
  case unsubscribe() => true
  case stop() => true
  case stopall() => true
  case cancel() => true
  case end() => true
  case quit() => true
  case _ => false
}

Upvotes: 0

jwvh
jwvh

Reputation: 51271

This will tell you if any of the Regex patterns match the 1st element in the massageBody array.

unsubscribeTriggers.exists(_.findAllIn(messageBody.head).nonEmpty)

But I don't think your regex patterns do what you want. What is the /i extension? If you mean for it to ignore case, it won't. It's also not a very efficient or Scala-esque way to do it. Instead of many smaller regex patterns, combine them into a single test.

val unsubscribeTriggers: Array[String] =
  Array("unsubscribe/i", "stop/i", "stopall/i", "cancel.i", "end/i", "quit/i")
val TriggersRE = unsubscribeTriggers.mkString("(", "|", ")").r

messageBody.head match {
  case TriggersRE(_) => true
  case _ => false
}

update

If you just need to compare strings, ignoring case, then try this.

val unsubscribeTriggers: Array[String] =
  Array("unsubscribe", "stop", "stopall", "cancel", "end", "quit")

unsubscribeTriggers.exists(messageBody.head.equalsIgnoreCase)

If you want to test if any element in massageBody matches any element in unsubscribeTriggers then try this.

unsubscribeTriggers.exists(t => messageBody.exists(t.equalsIgnoreCase))

Upvotes: 1

Assen Kolov
Assen Kolov

Reputation: 4393

You expect too much magic from the compiler. If you have a collection of regexes, you have to check yourself against every element:

val unsubscribeTriggers: Array[Regex] = Array("(?i)unsubscribe".r, "(?i)stop".r)

val body = "sToP"
val matchFound = unsubscribeTriggers.exists { p: Regex =>
 body match {
  case p() => true
  case _ => false
 }
}
println(matchFound)

Regex is made case insensitive by adding (?i) at the start. Try it.

Upvotes: 1

Related Questions