romatthe
romatthe

Reputation: 1477

Scala not perfoming an exact match

I'm relatively new to Scala, I'm trying to do some basic Regex pattern matching:

In the example below I'm trying to match a string that gets sent to an Akka TCP actor:

class ConnectionHandler extends Actor with ActorLogging {

  import Tcp._

  def receive = {
    case Received(data) => {
      log.info("Data received! " +  data)
      log.info("Date received! " + data.decodeString("UTF-8"))

      val pattern = """(?ms)(<START>>)(((.+?)=(.+?));)+(END)""".r

      val decoded = data.decodeString("UTF-8").trim

      decoded match {
        case pattern()      => log.info("OK")
        case pattern(t)     => log.info("A bit")
        case _              => log.info("NOK :(")
      }

      pattern findFirstIn decoded match {
        case Some(v) => log.info("Found: " + v); true
        case None => log.info("Not found") ; false
      }
    }

    case PeerClosed => {
      log.info("Peer closed!")
      context stop self
    }

    case _              => log.info("Received unknown message")
  }
}

Below is an example string that I'm receiving:

<START>>=ITM_NT_Logical_Disk;source='ITM';sub_source='Primary:PX810001999:NT';cms_hostname='pc120003350';cms_port='3661';integration_type='N';master_reset_flag='';appl_label='';situation_name='Y_WINDOWS_TEST';situation_type='S;Total_Size=152617~';END

As far as I an see, my Regex should work, though admittedly I'm not very good at them.

The strange thing is that the result for this part

decoded match {
    case pattern()      => log.info("OK")
    case pattern(t)     => log.info("A bit")
    case _              => log.info("NOK :(")
  }

is NOK, but the result for this part:

pattern findFirstIn decoded match {
    case Some(v) => log.info("Found: " + v); true
    case None => log.info("Not found") ; false
}

is that it not only finds a value, but it matches the entire exact string. (Value of 'v' is exactly that of the string sent over the wire, or that of 'decoded')

At first I thought the newline appended at the end of the string would cause the problem, but I added

val decoded = data.decodeString("UTF-8").trim

but no luck :(

I also tried simplifying the Regex to

val pattern = """(?ms)(<START>>).*?(END)""".r

but that doesn't seem to improve my results.

I want to make sure that the string ends exactly with "END", because I need to perform some manipulation afterwards, so findFirstIn is not preferable.

For the record, I've tried validating my Regex with a multitude of helper tools, but they all seem to indicate that I'm doing the right thing.

Upvotes: 0

Views: 967

Answers (1)

bjfletcher
bjfletcher

Reputation: 11508

That produces 6 match captures as shows by regex101 and therefore you can change your pattern matching as follows:

decoded match {
  case pattern(_, _, _, _, _, _) => log.info("OK")
  case _ => log.info("NOK :(")
}

Upvotes: 1

Related Questions