loneStar
loneStar

Reputation: 4010

Java/scala Regex Pattern is not Replacing the String

My input is the following.

 val source = """ {
        "tgtPartitionColumns" : "month_id="${month_id}"",
        "splitByCol" : "${splitByCol}"
        }"""

val inputArgsMap =  Map("splitByCol"->"ID","month_id"->"Jan")

My Function for the Regex Replace is the following

import scala.collection.mutable
import java.util.regex.Pattern    
def replaceVariablesWithValues(expr: String, argsMap: Map[String, String]): String = {
        val regex = "\\$\\{(\\w+)\\}"
        val unPassedVariables = new mutable.ListBuffer[String]()
        val pattern = Pattern.compile(regex)
        val matcher = pattern.matcher(expr)
        var replacedString: Option[String] = None
        while (matcher.find) {
          val key = matcher.group(1)
          if (argsMap.contains(key)) {
            replacedString = Some(expr.replace("${" + key + "}", argsMap(key)))
          } else {
            unPassedVariables += key
          }
        }
        if (unPassedVariables.nonEmpty)
          throw new IllegalStateException(s"No matching key found in input arguments for $unPassedVariables")
        replacedString.getOrElse("")
      }

It is able to detect the month_id as a group but is not getting replaced in the source.

Upvotes: 0

Views: 136

Answers (2)

Balint Pato
Balint Pato

Reputation: 1549

The regex is fine actually, you have a bug in your loop, this can fix it:

replacedString = Some(replacedString.getOrElse(expr).replace("${" + key + "}", argsMap(key)))

Upvotes: 2

Shane Perry
Shane Perry

Reputation: 990

On each match, you are re-using the original string for replacement. So the month_id replacement is lost when splitByCol is replaced. You need to change

replacedString = Some(expr.replace("${" + key + "}", argsMap(key)))

to something like

replacedString = Some(replacedString.getOrElse(expr).replace("${" + key + "}", argsMap(key)))

Upvotes: 1

Related Questions