如果特定字符串格式短于所需长度,则使用零填充特定字符串格式

时间:2016-12-04 07:47:50

标签: java string

我正在尝试创建一个程序来检查用户的序列号是否有效。它应符合特定格式。格式应该是两个数字,后跟一个破折号,四个数字,一个点,然后是四个数字和两个字符(注意:接受的字符只有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");
            }
        }
    }
}

1 个答案:

答案 0 :(得分: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);
      }
    }
  }
}