2

I have the below response from some telnet server

String response = "I:BARCO@noiclt22815||K:CMS||O:REgetPerspectiveList||A0:googleP||A1:yahooP||A2:gmail||A3:test||A4:hello||A16:CCTV Barco||A17:CCTV: Corridor CC||A18:CCTV: DR Andy Warhol||A19:CCTV: DR Gaudi (Analog)||A20:CCTV: DR Miro||A21:CCTV: Entrance CC||A22:CCTV: Gaudi Demo Room Megapixel||";

I want to get the attributes value for e.g A0, A1 etc and therefore I write the below logic

String[] strings = response.split("[||]");
List<String> list = new ArrayList<>();

for (String string : strings) {
    if (string.contains(":")) {
        String[] attributes = string.split(":");
        if (attributes[0].startsWith("A")) {
            list.add(attributes[1]);
        }
    }
}

But my problem is that string.split(":") split gives me string array but I requires only two length size string array only. For e.g. response A17 attribute gives me "CCTV" as attributes[1] and "Corridor CC" as attributes[2] but I requires "CCTV: Corridor CC" as attribute [1] only.

What regular expression I should write in string.split(regexp) so that string can be split based on first instance of colon operator only with exactly two length size string array.

Szymon
  • 42,577
  • 16
  • 96
  • 114
ashishgupta_mca
  • 578
  • 6
  • 27
  • You can use substring methods with indexOf to get the index of the first `:` and use substring till that index and put the two strings in array. – Tushar Jan 21 '16 at 04:55
  • I can do that but I want regex. – ashishgupta_mca Jan 21 '16 at 04:57
  • Pranav, it gives me same response as before means CCTV only for a17 attribute – ashishgupta_mca Jan 21 '16 at 04:59
  • 2
    [*Some people, when confronted with a problem, think “I know, I'll use regular expressions.” Now they have two problems.* -- Jamie Zawinski](http://regex.info/blog/2006-09-15/247) –  Jan 21 '16 at 04:59
  • *"If you can do something without a regular expression, that is probably the better way to do it"* –  Jan 21 '16 at 05:01
  • 1
    It's definitely not a duplicate of *that* question... – Makoto Jan 21 '16 at 05:03

3 Answers3

1

Set a limit on your split.

String[] attributes = string.split(":", 2);

This will force the regex to only be applied once (per the documentation it's applied n-1 times), so your groupings will only split on the colon character one time.

Once applied into the code, the result is as follows:

[googleP, yahooP, gmail, test, hello, CCTV Barco, CCTV: Corridor CC, CCTV: DR Andy Warhol, CCTV: DR Gaudi (Analog), CCTV: DR Miro, CCTV: Entrance CC, CCTV: Gaudi Demo Room Megapixel]
Makoto
  • 104,088
  • 27
  • 192
  • 230
1

The code below splits on pipes first, and then uses a regex to extract out the properties and attributes. Note that even there, you could probably get away with doing another split.

String response = "I:BARCO@noiclt22815||K:CMS||O:REgetPerspectiveList||A0:googleP||A1:yahooP||A2:gmail||A3:test||A4:hello||A16:CCTV Barco||A17:CCTV: Corridor CC||A18:CCTV: DR Andy Warhol||A19:CCTV: DR Gaudi (Analog)||A20:CCTV: DR Miro||A21:CCTV: Entrance CC||A22:CCTV: Gaudi Demo Room Megapixel||";
String[] metaParts = response.split("\\|\\|");

for (int i=0; i < metaParts.length; ++i) {
    String property = metaParts[i].replaceAll("(.*):(.*)", "$1");
    String attribute = metaParts[i].replaceAll("(.*):(.*)", "$2");
    System.out.println(property + ":" + attribute);
}

As others here have said, regular expressions are not a panacea to cure all your development problems. And splitting is definitely doing the heavy lifting for this problem.

Tim Biegeleisen
  • 502,043
  • 27
  • 286
  • 360
  • It really feels like this is a lot of work to accomplish something that regex perhaps really *shouldn't* be accomplishing... – Makoto Jan 21 '16 at 05:10
0
import java.util.HashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class TestRegex {

public static void main(String[] args) {

    String response = "I:BARCO@noiclt22815||K:CMS||O:REgetPerspectiveList||A0:googleP||A1:yahooP||A2:gmail||A3:test||A4:hello||A16:CCTV Barco||A17:CCTV: Corridor CC||A18:CCTV: DR Andy Warhol||A19:CCTV: DR Gaudi (Analog)||A20:CCTV: DR Miro||A21:CCTV: Entrance CC||A22:CCTV: Gaudi Demo Room Megapixel||";
    Matcher mat = Pattern.compile("([^\\:]+)\\:([^\\|]+)\\|\\|").matcher(response);
    HashMap<String, String> hm = new HashMap();
    while( mat.find() ) {
        if(mat.groupCount() > 0) {
            String k = response.substring( mat.start(1), mat.end(1));
            String v = response.substring( mat.start(2), mat.end(2));
            hm.put(k, v);

            System.out.println(k +  " => " + v);   // debug
        }
    }
    // you may refer to your data from hashmap hm here!
    System.out.println(hm.get("K"));
}

} // end class
Mohd Yunus
  • 11
  • 2