-1

I have to read commands from a file I have and take necessary actions according to each command. I was able to find out the process of reading from the file and what the command is, but I am having trouble transferring the specific information contained in the command to the program. As an example, the line read is as follows

Add id:12 name:"Sandik" singer:"Muslum Gurses" year:2009 count:5 price:20

I have separated this reading line in each space as u can see in below.

 Scanner scan = new Scanner(new File(args[0]));
 while (scan.hasNextLine()) {
      String data = scan.nextLine();
      String[] readedCommand = data.split(" ");

After this operation, readedCommands[0] gives me the read command. For the above example, readedCommands[0] = "Add"

After this step, I need to extract the information from the rest of the command, but I have no idea how to extract information such as id, name, singer. I will be grateful if you could help me. Thank you in advance.

Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110
Roxox
  • 99
  • 7
  • Does this answer your question? [javascript split string by space, but ignore space in quotes (notice not to split by the colon too)](https://stackoverflow.com/questions/16261635/javascript-split-string-by-space-but-ignore-space-in-quotes-notice-not-to-spli) – The Head Rush Oct 29 '20 at 18:44
  • @TheHeadRush Nope – Roxox Oct 30 '20 at 09:11
  • What have you tried so far? Why not split each remaining substring by the `:` and act upon that? – Nico Haase Nov 03 '20 at 11:23

3 Answers3

0

After you have the array then you can split each string again by split(":") to separate the key from the value. Use a HashMap to store the key and values.

HashMap<String, String> hmap = new HashMap<String, String>();
 while (scan.hasNextLine()) {
      String data = scan.nextLine();
      String[] readedCommand = data.split(" ");
      for(int i = 1; i < readedCommand.length; i++){
          String[] pair = readedCommand[i].split(";");
          hmap.put(pair[0], pair[1]);
      }

}
DCruz22
  • 806
  • 1
  • 9
  • 18
  • Splitting on the space character can improperly break strings values. – The Head Rush Oct 29 '20 at 18:39
  • Thank u for answer but I still don't know how I can access the information here. I tried printing things like pair [0] but it didn't work. Where is the divided information saved here? – Roxox Oct 29 '20 at 18:48
  • In short, I will send the information such as id, name, singer ... that I pulled from here to a linkedlist. In order to do this, I need variables to which this information is assigned. What exactly are these variables? – Roxox Oct 29 '20 at 18:49
  • And also when I update my code like u showed me, I tried to run it but it gave me Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 1 out of bounds for length 1 at Main.main(Main.java:38) – Roxox Oct 29 '20 at 18:55
0

You can do it by splitting the string twice:

  1. Split the given string, using the regex, \s(?=\w+:)
  2. Then iterate the resulting array from the index, 1 (because the string at index, 0 is the command) and split each element further on :

Demo:

public class Main {
    public static void main(String[] args) {
        String data = "Add id:15 singer:\"Tarkan\" name:\"Adimi Kalbine Yaz\" year:2010 count:10 price:20";

        // First, split on whitespace
        String[] parts = data.split("\\s(?=\\w+:)");

        // The first element in the array is the command
        String command = parts[0];
        System.out.println("Command: " + command);

        // Split the remaining elements on ':'
        for (int i = 1; i < parts.length; i++) {
            String[] keyVal = parts[i].split(":");
            if (keyVal.length == 2) {
                String key = keyVal[0];
                String value = keyVal[1];
                System.out.println("Key: " + key + ", Value: " + value);
            }
        }
    }
}

Output:

Command: Add
Key: id, Value: 15
Key: singer, Value: "Tarkan"
Key: name, Value: "Adimi Kalbine Yaz"
Key: year, Value: 2010
Key: count, Value: 10
Key: price, Value: 20

Explanation of the regex, \s(?=\w+:):

  1. \s specifies whitespace.
  2. (?=\w+:) specifies positive lookahead for one or more word character(s) followed by a :
Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110
  • Thank u for answer but there is something wrong. Name should be Sandik and singer should be Muslum Gurses. Not "Sandik" and "Muslum". How can we fix it ? – Roxox Oct 29 '20 at 19:02
  • @Roxox - I've rectified the problem. Feel free to comment in case of any doubt/issue. – Arvind Kumar Avinash Oct 29 '20 at 19:13
  • You are the best dude! – Roxox Oct 29 '20 at 20:29
  • The only problem with this code is if the song title is more than 1 word it only takes the first word. For this case: `Add id:15 singer:"Tarkan" name:"Adimi Kalbine Yaz" year:2010 count:10 price:20` it's output is : `Command: Add Key: id, Value: 15 Key: singer, Value: "Tarkan" Key: name, Value: "Adimi Key: year, Value: 2010 Key: count, Value: 10 Key: price, Value: 20` I tried making a few tweaks to the code, but I was almost breaking it even more. I wonder if there is any way we can handle this part? – Roxox Oct 29 '20 at 20:41
  • @Roxox - Let me check it. I will update the answer in a few minutes after analysing the problem. – Arvind Kumar Avinash Oct 29 '20 at 20:45
  • I am thankful to you. I am waiting for your reply. – Roxox Oct 29 '20 at 20:48
  • @Roxox - Corrected it. Feel free to comment in case of any further doubt/issue. – Arvind Kumar Avinash Oct 29 '20 at 20:54
  • String[] parts = data.split("(?<!\"\\w+)\\s+(?!\\w+\")"); in this line it says that + repetition not allowed inside lookbehind and there is a red line under the + (to the right of w) sign. I wonder if there is a syntax error? – Roxox Oct 29 '20 at 20:58
  • @Roxox - Different languages process regex in different ways. In Java, this is correct. In fact, I had also faced the same problem when I was trying on Regex101 but when I tried it in the Java program, it worked without any problem. You can also check it [here](https://ideone.com/okU0AP). Feel free to comment in case of any further doubt/issue. – Arvind Kumar Avinash Oct 29 '20 at 21:03
  • I tried run it in another IDE and when I run it it gaves me `Exception in thread "main" java.util.regex.PatternSyntaxException: Look-behind group does not have an obvious maximum length near index 7` – Roxox Oct 29 '20 at 21:04
  • @Roxox - No worries. I will post an alternative solution in a few minutes. – Arvind Kumar Avinash Oct 29 '20 at 21:05
  • @ ArvindKumarAvinash As long as this problem continues, I do not know how to continue writing the program. What can I do? – Roxox Oct 29 '20 at 21:06
  • Thank u very much! I'm waiting for you sir. – Roxox Oct 29 '20 at 21:06
  • @Roxox - I have rewritten the solution. Please check quickly and comment in case of any further doubt/issue as I feel tired after a hectic day and feeling sleepy now . – Arvind Kumar Avinash Oct 29 '20 at 21:39
  • I can't tell you how grateful I am. Everything works perfectly. I want to keep in touch with you. Can I contact you via Skype Discord Telegram Instagram or any other domain? I have a lot to learn from you. – Roxox Oct 29 '20 at 21:40
  • @Roxox - That's great! You are most welcome. Wish you success! You can connect with me through LinkedIn (you can find the link on my profile page ). – Arvind Kumar Avinash Oct 29 '20 at 21:42
  • I sent a request to follow. My name is Ayberk Saygı. Thank u for everything sir. – Roxox Oct 29 '20 at 21:46
  • Hello sir. I finished my project and again thank you for all. I want to ask you one last thing. Could you review my question from this link https://stackoverflow.com/questions/64647919/how-do-i-pass-arguments-sent-to-the-program-to-a-class-other-than-the-main-class I'm facing a strange error that is preventing part of my code from working. – Roxox Nov 02 '20 at 16:34
  • @Roxox - I saw your message an hour ago but I have been busy with meetings since then. I just checked your question and I am glad to see that it has already been solved. – Arvind Kumar Avinash Nov 02 '20 at 17:24
  • In fact, part of my question was solved thanks to that answer, but I marked it as a solution in order not to leave that friend's effort unpaid. I sent you a follow request from linkedin, but since I am not a premium member, I did not have the chance to reach you unless you reached me. I have only one problem now and if you examine the link I sent, you will see the problem. I cannot operate on args [2] inside my LinkedList class. I would be grateful if you could help, sir. – Roxox Nov 02 '20 at 17:40
  • hello sir how are you? I got a problem about my backtracking operation. If you free, can u take a look please ? https://stackoverflow.com/questions/64837325/unexpected-stack-operation-java?noredirect=1#comment114634284_64837325 – Roxox Nov 14 '20 at 19:06
0

Consider the following code. Comments in the code serve as explanation of what it does.

// Text block, first introduced as preview feature in JDK 13
String str = """
        Add id:12 name:"Sandik" singer:"Muslum Gurses" year:2009 count:5 price:20\
        """;
String[] parts = str.split(" ", 2);  // Create an array with no more than two elements.
System.out.println(Arrays.toString(parts));

// A single space that is not preceded by a quote mark followed by one or more word characters
// and also not succeeded by a string of one or more word characters followed by a quote.
String regex = "(?<!\"\\w+)\\s(?!\\w+\")";

// Splits on every space except for the space between 'Muslum' and 'Gurses'.
String[] list = parts[1].split(regex);
System.out.println(Arrays.toString(list));

// Used in the stream operation below.
// Split the string (elem) at the colon character and return the first array element.
Function<String, String> keyMapper = elem -> elem.split(":")[0];

// Used in the stream operation below.
Function<String, String> valueMapper = elem -> elem.split(":")[1];

Map<String, String> map = Arrays.stream(list)
                                .collect(Collectors.toMap(keyMapper, valueMapper));
System.out.println(map);

Running above code produces the following output.

[Add, id:12 name:"Sandik" singer:"Muslum Gurses" year:2009 count:5 price:20]
[id:12, name:"Sandik", singer:"Muslum Gurses", year:2009, count:5, price:20]
{singer="Muslum Gurses", year=2009, price=20, name="Sandik", count=5, id=12}
Abra
  • 19,142
  • 7
  • 29
  • 41
  • Just FYI: I've been penalized a few times for explaining the things just through comments in the code and not putting an explanation outside the code. Check [this](https://stackoverflow.com/a/64396780/10819573) for an example. Like you, I do not see a problem with this style of explaining but the mass has a different opinion. – Arvind Kumar Avinash Nov 02 '20 at 20:42