Home > Software design >  How can I parse a string by mutliple delimiters using Java8 or regex
How can I parse a string by mutliple delimiters using Java8 or regex

Time:06-30

I have a List<String> like this:

List.of(
  "ParamField(paramName=Thomas, paramValue=Admitted)",
  "ParamField(paramName=Martin, paramValue=Discarded)",
  "ParamField(paramName=Steve, paramValue=Admitted)"
);

How can I iterate the list and parse all string in such a way that at the end of iteration I can have a single string which contains something likes this

String s = "Thomas-Admitted;Marting-Discarded;Steve-Admitted";

CodePudding user response:

Regex

This is fairly easy to achieve with regex capturing groups. Your pattern will be "ParamField\\(paramName=(. ), paramValue=(. )\\)" and then you simply match and get group(1) and group(2).

Once you extracted that, simply create the string with a StringJoiner on ; or similar.

Could look something like this:

Pattern pattern = Pattern.compile("ParamField\\(paramName=(. ), paramValue=(. )\\)");

StringJoiner sj = new StringJoiner(";");
for (String paramField : paramFields) {
  Matcher matcher = pattern.matcher(paramField);
  if (!matcher.find()) {
    throw new IllegalArgumentException("Bad input format");
  }

  String name = matcher.group(1);
  String value = matcher.group(2);

  sj.add(name   "-"   value);
}

String result = sj.toString();

With OOP

Ideally you would employ some OOP though and create a nice record ParamField with a factory method on that string and then use its getters. That way its easier to keep working with the data, in case you need to do more with it.

record ParamField(String name, String value) {
  private static Pattern pattern = Pattern.compile(
    "ParamField\\(paramName=(. ), paramValue=(. )\\)");

  static ParamField of(String line) {
    Matcher matcher = pattern.matcher(line);
    if (!matcher.find()) {
      throw new IllegalArgumentException("Bad input format");
    }
    return new ParamField(matcher.group(1), matcher.group(2));
  }
}

with a usage like

List<ParamField> paramFields = lines.stream()
  .map(ParamField::of)
  .toList();

and then work with that data. For example build your string:

String result = paramFields.stream()
  .map(paramField -> paramField.name()   "-"   paramField.value())
  .collect(Collectors.joining(";"));

Enum

If you need to do more complex stuff with the data, I would suggest you go one step further and also put the value into an enum, such as:

enum ParamValue {
  ADMITTED("Admitted"),
  DISCARDED("Discarded");

  // field, constructor, getter, of-method
}

so that you do not have to work with raw strings anymore but get all the type-safety Java can provide to you.

CodePudding user response:

Using Pattern and Matcher classes with Stream API:

Pattern pattern = Pattern.compile("ParamField\\(paramName=(. ), paramValue=(. )\\)");

var result = Stream.of(
                "ParamField(paramName=Thomas, paramValue=Admitted)",
                "ParamField(paramName=Martin, paramValue=Discarded)",
                "ParamField(paramName=Steve, paramValue=Admitted)"
        ).map(pattern::matcher)
        .filter(Matcher::find)
        .map(m -> String.format("%s-%s", m.group(1), m.group(2)))
        .collect(Collectors.joining(";"));

System.out.println(result);

CodePudding user response:

Using Simple substring and index of

ArrayList list=new ArrayList();
      List.of(
            "ParamField(paramName=Thomas, paramValue=Admitted)",
            "ParamField(paramName=Martin, paramValue=Discarded)",
            "ParamField(paramName=Steve, paramValue=Admitted)"
    ).forEach(item->{
          list.add(item.substring(21,item.lastIndexOf(",")) "-" item.substring(item.lastIndexOf("ue=") 3,item.lastIndexOf(")")));
    });
    String s =list.toString();

CodePudding user response:

"ParamField([email protected], paramValue=Admitted)"

  • Related