1
votes

I need to create a regular expression to identify key value pairs which are separated by commas. Key and value can have letters (both upper case and lower case), digits, special characters (- _ , / .). Following regular expression works when special characters follow alphanumeric characters but when the special character comes before alphanumeric characters, it does not work. For example "key1.=value1-;key2/=value2-" works but ".key1=value1-;key2/=value2-" does not work.

import scala.util.matching.Regex

object TestReges {
  def main(args: Array[String]): Unit = {
//val inputPattern : String= "1one-=1;two=2"
//val inputPattern : String = "-"
//val inputPattern : String= "two"
val inputPattern : String= "key1-=value1;key2=,value2."
val tagValidator:  Regex = "(?:(\\w*\\d*-*_*,*/*\\.*)=(\\w*\\d*-*_*,*/*\\.*)(?=;|$))".r
//Pattern p = Pattern.compile("(?:(^[a-z]+)=(^[a-z]+)(?=&|$))");
//Matcher m = p.matcher(input);
//System.out.println(m.groupCount());
println(tagValidator.findAllMatchIn(inputPattern).size)
//    while (m.find()) {
//      System.out.println("key="+m.group(1));
//      System.out.println("value="+m.group(2));
//    }
}  }
2
This seems awfully complicated for what you need. Can't you just split on ; and then =?shmosel

2 Answers

2
votes

Why not split on the separator and then just match everything on either side of the = that isn't an =?

//Scala code
val kvPair = "([^=]+)=([^=]+)".r

List("key1.=value1-;key2/=value2-",".key1=value1-;key2/=value2-")
  .flatMap(_.split(";"))
  .collect{case kvPair(k,v) => k -> v}
//res0: List[(String, String)] = List((key1.,value1-)
//                                  , (key2/,value2-)
//                                  , (.key1,value1-)
//                                  , (key2/,value2-))
0
votes

Why do you want to do it with regex as @shmosel specified why can't you just split it on ; and then on = ? like this

val inputPattern : String= "key1-=value1;key2=,value2."
inputPattern.split(";").map{ kvStr => kvStr.split("=") match 
case Array(k, v) => (k, v)
}.toMap