2016-12-04 4 views
2

Я пытаюсь создать программу, которая проверяет, действительно ли серийные коды пользователя действительны или нет. Он должен соответствовать определенному формату. Формат должен состоять из двух цифр, за ними следует тире, четыре цифры, точка, затем четыре цифры и два символа (примечание: принятые символы - только a, b и c).Заполнение определенного строкового формата нулями, если он меньше требуемой длины

Example valid format: 

31-0001.2341ac 
00-9999.0001cb 

Если серийный код является недействительным, поскольку он не соответствует требуемой длины строки, программа должна заполнить его нулями в начале и новый код будет напечатан.

Мне удалось работать с программой проверки серийного кода с использованием регулярных выражений, теперь она корректно проверяет, является ли код действительным или нет. Тем не менее, я считаю это сложным, когда ему нужно создать новый код для недопустимого серийного кода. Это все равно, что мне нужен жесткий код для всех возможных комбинаций.

Я пробовал следовать этому How to format a Java string with leading zero?, но мне тяжело, потому что в моем строковом формате есть черточка & в середине строки.

Я все еще довольно новый, я еще не знаком с utils или библиотеками для таких функций. Я надеюсь, что кто-то может помочь мне исправить мой код, чтобы сделать его более простым и эффективным.

import java.util.Scanner; 

public class SerialCheck { 
    public static void main(String[] args) { 
     Scanner sc = new Scanner(System.in); 

     System.out.print("How many serial numbers would you like to check: "); 
     int length = sc.nextInt(); 
     int valid = 0; 

     String[] sSerials = new String[length]; 

     for (int nCtr = 0; nCtr < length; nCtr++) { 
      System.out.print("Enter Serial " + (nCtr + 1) + ": "); 
      sSerials[nCtr] = sc.next(); 
     } 

     System.out.println(); 
     System.out.println("The following were added: "); 
     for (int nCtr = 0; nCtr < length; nCtr++) { 
      System.out.println(sSerials[nCtr]); 
     } 

     System.out.println(); 
     System.out.println("Comments\t" + "New Code"); 
     for (int nCtr = 0; nCtr < length; nCtr++) { 
      boolean isValid = sSerials[nCtr].matches("[0-9]{2}-[0-9]{4}\\.[0-9]{4}[abc0-9]{2}"); 
      boolean isMissing = sSerials[nCtr].matches("[0-9]{2}-[0-9]{4}\\.[0-9]{1}[abc0-9]{2}") || 
       sSerials[nCtr].matches("[0-9]{2}-[0-9]{4}\\.[0-9]{2}[abc0-9]{2}") || 
       sSerials[nCtr].matches("[0-9]{2}-[0-9]{4}\\.[0-9]{3}[abc0-9]{2}"); 
      boolean isMissing1 = sSerials[nCtr].matches("[0-9]{2}-[0-9]{1}\\.[0-9]{4}[abc0-9]{2}") || 
       sSerials[nCtr].matches("[0-9]{2}-[0-9]{2}\\.[0-9]{4}[abc0-9]{2}") || 
       sSerials[nCtr].matches("[0-9]{2}-[0-9]{3}\\.[0-9]{4}[abc0-9]{2}"); 
      boolean isMissing2 = sSerials[nCtr].matches("[0-9]{0}-[0-9]{4}\\.[0-9]{4}[abc0-9]{2}") || 
       sSerials[nCtr].matches("[0-9]{1}-[0-9]{4}\\.[0-9]{4}[abc0-9]{2}"); 

      if (isValid) { 
       System.out.println("Valid\t\t" + sSerials[nCtr]); 
      } else if (isMissing) { 
       System.out.println("Invalid\t\t" + sSerials[nCtr].substring(0, 8) + "0000".substring(0, 14 - sSerials[nCtr].length()) + sSerials[nCtr].substring(8)); 
      } else if (isMissing1) { 
       System.out.println("Invalid\t\t" + sSerials[nCtr].substring(0, 3) + "0000".substring(0, 14 - sSerials[nCtr].length()) + sSerials[nCtr].substring(3)); 
      } else if (isMissing2) { 
       System.out.println("Invalid\t\t" + sSerials[nCtr].substring(0, 0) + "00".substring(0, 14 - sSerials[nCtr].length()) + sSerials[nCtr].substring(0)); 
      } else { 
       System.out.println("Invalid\t"); 
      } 
     } 
    } 
} 
+0

@Andrew быстрый вопрос для уточнения требований. Если кто-то вводит неверный серийный '2341ac', вы хотите, чтобы ваша программа генерировала' 00-0000.2341ac', '000000002341ac' или что-то еще? Кроме того, если бы вы могли точно сформулировать вопрос, это помогло бы мне кратко ответить. Я думаю, что получаю то, о чем вы просите, но я хочу проверить. – entpnerd

+0

@entpnerd, если они вводят 2341ac, это должно быть 00-0000.2341ac – Andrew

+0

В настоящее время, как работает моя программа, я пытаюсь найти все возможные комбинации, где пользователь может пропустить цифру на любой части строки и просто просто заполнить ее нулями в начале. Поэтому Im просто ищет другое решение, чтобы упростить его. – Andrew

ответ

1

В принципе, ваша стратегия определения конкретно отсутсвует. Другой подход состоял бы в том, чтобы просто наложить полные нули до тех пор, пока не будет достигнута правильная длина, а затем замените каждый символ по необходимости, если он слишком короткий или если формат сломан. Заметим также, что исходный вопрос не учитывал, если строка слишком длинная, поэтому я просто предположил, что вы можете рассматривать ее как все нули для простоты. Также см. Пример кода с образцами ввода в JDoodle. См. Приведенный ниже пример кода:

import java.util.regex.Matcher; 
import java.util.regex.Pattern; 
import java.util.Scanner; 

public class SerialCheck { 

    private static String leftPadWithX(String shortStr) { 
    StringBuilder paddableString = new StringBuilder(shortStr); 
    for (int i = 14 - shortStr.length(); i > 0; --i) { 
     paddableString.insert(0, 'X'); 
    } 
    assert paddableString.length() == 14; 
    return paddableString.toString(); 
    } 

    private static String fix(String broken) { 
    assert broken.length() == 14; 
    StringBuilder mutableBroken = new StringBuilder(broken); 
    for(int i = 0; i < 14; ++i) { 
     // not exactly a char, but need a 1 element string for regex matching 
     String brokenChar = "" + mutableBroken.charAt(i); 
     if (i < 2 && !Pattern.matches("\\d", brokenChar)) { 
     mutableBroken.replace(i, i+1, "0"); 
     } else if (i == 2 && !Pattern.matches("-", brokenChar)) { 
     mutableBroken.replace(i, i+1, "-"); 
     } else if (i > 2 && i < 7 && !Pattern.matches("\\d", brokenChar)) { 
     mutableBroken.replace(i, i+1, "0"); 
     } else if (i == 7 && !Pattern.matches("\\.", brokenChar)) { 
     mutableBroken.replace(i, i+1, "."); 
     } else if (i > 7 && i < 12 && !Pattern.matches("\\d", brokenChar)) { 
     mutableBroken.replace(i, i+1, "0"); 
     } else if (i >= 12 && i < 14 && !Pattern.matches("[abc\\d]", brokenChar)) { 
     mutableBroken.replace(i, i+1, "0"); 
     } 
    } 
    return mutableBroken.toString(); 
    } 

    public static void main(String[] args) { 
    Scanner sc = new Scanner(System.in); 

    System.out.print("How many serial numbers would you like to check: "); 
    int length = sc.nextInt(); 
    int valid = 0; 

    String[] sSerials = new String[length]; 

    for (int nCtr = 0; nCtr < length; nCtr++) { 
     System.out.print("Enter Serial " + (nCtr + 1) + ": "); 
     sSerials[nCtr] = sc.next(); 
    } 

    System.out.println(); 
    System.out.println("The following were added: "); 
    for (int nCtr = 0; nCtr < length; nCtr++) { 
     System.out.println(sSerials[nCtr]); 
    } 

    System.out.println(); 
    System.out.println("Comments\t" + "New Code"); 
    for (int nCtr = 0; nCtr < length; nCtr++) { 
     boolean isValid = sSerials[nCtr].matches("[0-9]{2}-[0-9]{4}\\.[0-9]{4}[abc0-9]{2}"); 
    if (isValid) { 
     System.out.println("Valid\t\t" + sSerials[nCtr]); 
    } else if (sSerials[nCtr].length() > 14) { 
     // if too long, create all padded zeros 
     System.out.println("Invalid\tToo long\t00-0000.000000"); 
    } else if (sSerials[nCtr].length() < 14) { 
     // too short, pad with 0s unconditionally and fix format 
     String xPadded = leftPadWithX(sSerials[nCtr]); 
     String fixed = fix(xPadded); 
     System.out.println("Invalid\tToo short\t" + fixed); 
    } else { 
     // right length but bad format 
     String fixed = fix(sSerials[nCtr]); 
     System.out.println("Invalid\tBad format\t" + fixed); 
     } 
    } 
    } 
} 
+0

Я попытался скомпилировать его, но я получаю ошибки. SerialCheck1.java:21: ошибка: не удается найти символ , если (я <2 && Pattern.matches ("\\ d", brokenChar!)) { ^ символ: переменная Pattern местоположение: класс SerialCheck1 – Andrew

+0

Забыла добавить импорт для Pattern и Matcher. Просто отредактировал код. Попробуй. – entpnerd

0

Ваша проблема состоит из двух частей.

Первая часть разбора - возможно, неверный - вход.

Вторая часть форматирует ее с помощью ведущих нулей.

Вторая часть довольно проста. Вы просто создаете массив символов длиной 12, заполняете его нулями, затем заполняете его своими данными (начиная с конца), создавайте из него три строки и только s0 + "-" + s1 + "." + s0.

Первая часть может быть такой же простой или сложной, какой вы хотите. Есть - и . Значительные разделители?

Если нет, просто удалите их из строки, и у вас есть результат (ну, чтобы преобразовать в массив символов еще).

Если да, что произойдет, если эти разделители отсутствуют? Что произойдет, если ограниченная часть больше, чем предполагалось? Я хочу сказать, что сначала нужно определить правила для синтаксического анализа. Как только вы это сделаете, у вас будет хорошая идея о том, как должен выполняться синтаксический анализ.

+0

Да, если разделители отсутствуют, программа должна исправлять формат, подавая нули в начале, чтобы заполнить всю длину, включая - и. на их правильном положении. Вы бы предположили, что я просто использую массив символов, который проверяет входную строку пользователя вместо обычного выражения, которое находит точное совпадение? – Andrew

+0

Нет, я предлагаю вам определить правила для анализа недопустимого ввода, а затем реализовать их. Я не предлагаю массив символов против regex, это слишком творческая интерпретация. Однако, если вы напишете свои правила синтаксического анализа, вы, вероятно, заметите, что регулярное выражение не лучший выбор, так как вам нужно будет писать регулярное выражение для каждой возможной комбинации. Формальные грамматики, вероятно, также были бы излишними, поэтому я думаю, что лично мне пришлось бы жестко кодировать эти правила с помощью 'if',' else', 'indexOf' и' substring' для синтаксического анализа ввода на три части, которые вам понадобятся , – lexicore

Смежные вопросы