3

I am new to scala. I am trying something on the regular expression pattern matching. I am following the example from here: https://alvinalexander.com/scala/how-to-extract-parts-strings-match-regular-expression-regex-scala

Given below is the code that I have written which works but is obviously not the best way.
Scenario: I have a regex pattern with me.

"([a-z0-9]+)_([0-9]+)_([v|V][0-9]+)_(\\d{4})(\\d{2})(\\d{2}).(xls|xlsx)".r

I have a string that defines what I am expecting for a given scenario.
val param = "manufacturer/order/version"

Question: I don't want to pass hardcoded values in case pattern(manufacturer, order, version) but get the output in the variables manufacturer, order and version? One way is defining all the variables initially, but that would mean changing the code every time i need to change a string. Is there a way to do it dynamically or a better way of using regex in scala.

package com.testing

class DynamicFolder() {

  def dynamicPath(fileName: String): Map[String, String] = { 
    println("File Name: " + fileName)

    val param = "manufacturer/order/version"

    var patternString = param.replaceAll("/", ", ")
    println(patternString)

    val pattern = "([a-z0-9]+)_([0-9]+)_([v|V][0-9]+)_(\\d{4})(\\d{2})(\\d{2}).(xls|xlsx)".r
    val paramMap: Map[String, String] = fileName match {
      case pattern(manufacturer, order, version) => {
        println(s"Manufacturer: $manufacturer, Order: $order, version: $version")
        Map("manufacturer" -> manufacturer, "order" -> order, "version" -> version)
      }

      case pattern(manufacturer, order, version, yyyy, mm, dd, format) => {
        println(s"Manufacturer: $manufacturer, Order: $order, version: $version")
        Map("manufacturer" -> manufacturer, "order" -> order, "version" -> version)
      }

      case _ => throw new IllegalArgumentException
    }  
    paramMap
  }
}

object hello {

  def main(args: Array[String]): Unit = {
    var dynamicFolder = new DynamicFolder

    val fileName = "man1_18356_v1_20180202.xls"
    val tgtParams = dynamicFolder.dynamicPath(fileName)
    var tgtPath = "" 
    for ((k, v) <- tgtParams) {
      printf("key: %s, value: %s\n", k, v)
      tgtPath = tgtPath + "/" + tgtParams(k)
    }

    println ("Target path: "+tgtPath)
  }
}


Output of the code:

File Name: man1_18356_v1_20180202.xls
manufacturer, version, order
Manufacturer: man1, Order: 18356, version: v1
key: manufacturer, value: man1
key: order, value: 18356
key: version, value: v1
Target path: /man1/18356/v1

Thanks!

6
  • Do you mean you want to capture all groups in a single Seq which you can then access using indexes? Commented May 1, 2018 at 13:03
  • Hi Dennis, Yes more on that line. Thanks! Commented May 1, 2018 at 13:13
  • Ex. Instead of passing all values hardcoded, I want to get the values in run time <br />case pattern(manufacturer, order, version, yyyy, mm, dd, format)<br / > and store the values from the actual string against each of these values. Sometimes, I might need only 3 values which may not be in order, ex: I may need order, version and dd once the pattern matching is successful. Commented May 1, 2018 at 13:18
  • Are you just looking to replace the variables with something like: case pattern(groups@_*)? that would give you access to all values in a more dynamic way. Commented May 1, 2018 at 13:18
  • Can you please provide me the snippet so that I can test? Thanks! Commented May 1, 2018 at 17:12

1 Answer 1

0

This is how you can collect all groups and process them yourself:

val paramMap: Map[String, String] = fileName match {
    case pattern(groups@_*) if groups.nonEmpty => {
        // Access group with groups(0), groups(1) etc.
    }

    case _ => throw new IllegalArgumentException
}
Sign up to request clarification or add additional context in comments.

2 Comments

Hi Dennis, Thanks for the response.Can you please explain what the code is doing - (groups@_*) and how can I create a map by passing my variable name from here - val param = "manufacturer/order/version" for each of the groups values? I don't want to hardcode it like val manufacturer = groups(0) or val order = groups(1)
Thanks, I was able to resolve this using array, list, zip functions in scala

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.