2017-01-04 2 views
1

Как разбить строку ввода пользователя в отдельные строки и хранить, например, если входной формат следующим образом (для диаграммы результатов) ..Как разделить пользовательский ввод с консоли?

home_name : away_name : home_score : away_score 

Как бы я идти о расщеплении входа в 4 разные части и хранить отдельно? (Пользователю будет предложено ввести только в вышеуказанном формате, и я использую цикл while, чтобы продолжить запрашивать результаты линии до тех пор, пока пользователь не остановится).

+4

токенизатор или .split функция –

+2

Как [это] (HTTP: // StackOverflow .com/вопросы/3481828/как к сплит-а-строка-в-Java). Но есть ли у вас контроль над процессом ввода? Эта длинная строка кажется сложной/подверженной ошибкам. –

+0

Нет, это вопрос, который я пытаюсь развернуть, вход должен быть в одной строке и в указанном формате, например, типичный ввод будет выглядеть как manchester united: chelsea: 3: 2 – gv555

ответ

4

Если формат входных данных соответствует, то вы можете просто использовать шаблон : и сделайте следующее:

public static void main(String[] args) { 
    /* Scan Inputs */ 
    Scanner in = new Scanner(System.in); 

    /* Input String */ 
    String input = null; 

    /* Create StringBuilder Object */ 
    StringBuilder builder = new StringBuilder(); 

    String[] headers = { "home_name: ", "away_name: ", "home_score: ", 
      "away_score: " }; 
    while (null != (input = in.nextLine())) { 
     /* Break if user enters stop */ 
     if ("stop".equalsIgnoreCase(input)) { 
      break; 
     } 

     /* Trim the first and the last character from input string */ 
     input = input.substring(1, input.length() - 1); 

     /* Split the input string using the required pattern */ 
     String tokens[] = input.split(" : "); 

     /* Print the tokens array consisting the result */ 
     for (int x = 0; x < tokens.length; x++) { 
      builder.append(headers[x]).append(tokens[x]).append(" | "); 
     } 
     builder.append("\n"); 
    } 

    /* Print Results & Close Scanner */ 
    System.out.println(builder.toString()); 
    in.close(); 
} 

Обратите внимание, что здесь я использовал substring() функцию, чтобы избавиться от < и > в начало и конец входной строки перед ее разбиением с использованием заданного шаблона.

Вход:

<manchester united : chelsea : 3 : 2> 
<foobar : foo : 5 : 3> 
stop 

Выход:

home_name: manchester united | away_name: chelsea | home_score: 3 | away_score: 2 | 
home_name: foobar | away_name: foo | home_score: 5 | away_score: 3 | 
+1

Блестящий, и я могу как-то червять это в цикл while, чтобы продолжать запрашивать пользователя для другой строки, пока пользователь не остановится? – gv555

+0

@ gv555 Да, вы можете сделать это легко, используя «Сканер» для захвата входных данных пользователя с помощью консоли или, возможно, файла. См. Обновленный код. – user2004685

+1

Большое вам спасибо! Последний вопрос, как я могу изменить выход? Я бы хотел, чтобы это было на одной строке, и можно сделать вывод, поскольку пользователь вводит больше результатов, например, типичный результат может выглядеть как home_name [home_score] | away_name [away_score] и будет расти строка за раз по мере ввода результатов? – gv555

1

В некоторых случаях вход может быть немного 'несовместимым': пробелы, не предусмотренные или изменения, произведенные новыми версиями. Если это так, можно применить некоторую защиту с регулярными выражениями.

public static void main(String[] args) { 

    boolean validInput = false; 

    String input = "<home_name : away_name : home_score : away_score>"; 

    String pattern = "<.*:.*:.*:.*>"; 
    Pattern r = Pattern.compile(pattern); 
    Matcher m = r.matcher(input); 
    validInput = m.matches(); 

    if(validInput) { 
     input = input.substring(1, input.length() - 1); 
     String tokens[] = input.split("\\s*:\\s*"); 

     for (int x = 0; x < tokens.length; x++) { 
      System.out.println(tokens[x]); 
     } 

    } else { 
     System.out.println("Input is invalid"); 
    } 
} 
+0

Любые другие советы по проверке? Я хотел бы знать, как проверить, не указано ли имя одного из команд, или если один из показателей не является допустимым целым числом? – gv555

+0

@ gv555 Мы можем изменить регулярные выражения, чтобы избежать отсутствия значений и определить несогласованность типа данных. Шаблон может быть изменен на следующий: 'String pattern = <\\ s * \\ S + \\ s *: \\ s * \\ S + \\ s *: \\ s * \\ d + \\ s *: \\ s * \\ d + \\ s *> ";' Новый шаблон требует по крайней мере одного символа небелого пробела (\ S) в первом и втором полях и по меньшей мере одну десятичную цифру (\ d) в третьего и четвертого полей.Допускаются лишние символы пробела. –

0

Если формат точно так, как вы описали, довольно эффективный способ синтаксического анализа заключается в следующем:

public static void main(String[] args) { 
    String line = "<Raptors : T-Rexes : 5 : 10>"; 

    final int colonPosition1 = line.indexOf(':'); 
    final int colonPosition2 = line.indexOf(':', colonPosition1 + 1); 
    final int colonPosition3 = line.indexOf(':', colonPosition2 + 1); 

    final String homeName = line.substring(1, colonPosition1 - 1); 
    final String awayName = line.substring(colonPosition1 + 2, colonPosition2 - 1); 
    final int homeScore = Integer.parseInt(line.substring(colonPosition2 + 2, colonPosition3 - 1)); 
    final int awayScore = Integer.parseInt(line.substring(colonPosition3 + 2, line.length() - 1)); 

    System.out.printf("%s: %d vs %s: %d\n", homeName, homeScore, awayName, awayScore); 
} 
Смежные вопросы