验证字符串(PPS号)

时间:2013-12-04 21:06:40

标签: java string loops

好的,我正在尝试验证字符串(在本例中为PPS编号)。我似乎无法让它正常工作。

以下是问题:

  

每位爱尔兰公民在达到年龄后都会获得一个PPS号码   18是他们独有的,用于税收目的。一个有效的   PPS号码总共有8或9个字符。它将开始   正好是7位数字,以一个或两个大写字母结尾。所以,   例如,1234567A将被视为有效的PPS号码   7863456RT,但6478TY *%&和8768086b都被视为无效   PPS号码。

package Assess2013Two;
import java.util.Scanner;
public class Group3Solution {
    public static void main(String[] args)
    {
        int index = 0;
        char ch;
        Scanner input = new Scanner(System.in);

        System.out.print("Please enter your PPS number: ");
        String ppsNumber = input.nextLine();

        if(ppsNumber.length() >= 8 && ppsNumber.length() <= 9){
            if(ppsNumber.charAt(7) >= 'A' && ppsNumber.charAt(7) <= 'Z' && ppsNumber.charAt(8) >= 'A' && ppsNumber.charAt(8) <= 'Z')
            {
                if(ppsNumber.length() == 8) {
                    ch = ppsNumber.charAt(index);
                    while(index < ppsNumber.length() && ch >= '0' && ch <= '9'){
                        index++;
                        if(index < ppsNumber.length())
                            ch = ppsNumber.charAt(index);
                    }
                    if(index == ppsNumber.length())
                        System.out.println("You entered a valid PPS number.");
                    else
                        System.out.println("Invalid PPS number!! At least one of the first 7 characters were not digits.");
                }else {
                    ch = ppsNumber.charAt(index);
                    while(index < ppsNumber.length()-2 && ch >= '0' && ch <= '9'){
                        index++;
                        if(index<ppsNumber.length()-2)
                            ch = ppsNumber.charAt(index);
                    }
                    if(index == ppsNumber.length()-2)
                        System.out.println("You entered a valid PPS number.");
                    else
                        System.out.println("Invalid PPS number!! At least one of the first 7 characters were not digits.");
                }


            }else
                System.out.println("Invalid PPS number!! The second-last or last, or both, were not uppercase letters");
        }else
            System.out.println("Invalid PPS number!! It must contain at least 8 to 9 characters.");

        input.close();
    }
}

4 个答案:

答案 0 :(得分:4)

我更喜欢这类问题的正则表达式。

if(ppsNumber.matches("\\d{7}[A-Z]{1,2}"))
{ 
  // valid
}
else
{
  //invalid
}

答案 1 :(得分:2)

有很多问题。我发现的第一个是:

index = 6;
ch = ppsNumber.charAt(index);
while(index < ppsNumber.length() && ch >= '0' && ch <= '9'){
    index--;
    if(index < ppsNumber.length())
        ch = ppsNumber.charAt(index);
}
if(index == ppsNumber.length()-1)
    System.out.println("You entered a valid PPS number.");

这是一个超出范围的String索引,因为您检查index <但是您正在递减。它应该是这样的:

index = 6;
ch = ppsNumber.charAt(index);
while(index < 0 && ch >= '0' && ch <= '9'){
    index--;
    ch = ppsNumber.charAt(index);
}

然后这是因为你正在减少:

if(index == 0)
    System.out.println("You entered a valid PPS number.");

如果条目长度为8位且最后一位数字不是大写字母(“8768086b”),那么此行也会超出界限:

if(ppsNumber.charAt(7) >= 'A' && ppsNumber.charAt(7) <= 'Z' || ppsNumber.charAt(8) >= 'A' && ppsNumber.charAt(8) <= 'Z')

因为前两次检查失败并继续||。对于末尾有两个字母的数字,此逻辑也无法正常工作,因为只有一个必须通过。这可能是我能想到的“内联”整个陈述的最优雅的方式:

if( ppsNumber.charAt(7) >= 'A' && ppsNumber.charAt(7) <= 'Z' &&

  ( ppsNumber.length() == 8 ||
    ppsNumber.charAt(8) >= 'A' && ppsNumber.charAt(8) <= 'Z' ) ) {

但那看起来很复杂。如果条件相反,请参见下文。然后你可以将它分成两个检查(确实是这样)。

在这些更改之后,它会针对您指定的输入正确运行。

作为一般风格的注释,你应该尝试编写代码,这样你就不会有太多的缩进。你做了很多这样的事情:

if (/* some check */) {
    /* indent and do a whole lot of stuff */

} else {
    /* it's not valid */
}

除了导致更多缩进之外,如果if块内的代码很长,那么很难分辨出else块引用的内容。通常以下是更清洁的IMO:

if (/* reverse the check */) {
    /* it's not valid */
    return;
}

/* do a whole lot of stuff */

这使您的代码整洁有序。例如,请参阅以下内容:

Scanner in = new Scanner(System.in);

try {
    String num = in.nextLine();

    if (num.length() < 8 || num.length() > 9) {
        System.out.println("it was invalid");
        return;
    }

    char check = num.charAt(7);

    if (check < 'A' || check > 'Z') {
        System.out.println("it was invalid");
        return;

    } else if (num.length() == 9) {
        check = num.charAt(8);

        if (check < 'A' || check > 'Z') {
            System.out.println("it was invalid");
            return;
        }
    }

    for (int i = 0; i < 7; i++) {
        check = num.charAt(i);

        if (check < '0' || check > '9') {
            System.out.println("it was invalid");
            return;
        }
    }

    System.out.println("it was valid");

} finally {
    in.close();
}

你也不应该混合使用支撑和非支撑的if / else语句:

if (/*    */) {

} else
    /*        */;

阅读起来非常困难。选择一个或另一个,而不是两者。

同样的事情是“下一行”和“行尾”支撑风格:

if (/*    */)
{
    while (/*    */) {

    }
}

选择其中一个。

如果您将来提出问题,您还应该描述您遇到的具体问题,而不仅仅是“无法正常工作”。 “不起作用”并没有告诉我们任何有关如何提供帮助的信息,而且有些人合理地不愿意或无法执行该程序。特别是当涉及到例外情况时。发布堆栈跟踪并指出引发错误的行。显而易见,至少应该包含一个例外,那就是什么。

答案 2 :(得分:0)

它与您的index变量有关。你有这个循环:

index = 6;
ch = ppsNumber.charAt(index);
while(index < ppsNumber.length() && ch >= '0' && ch <= '9'){
  index--;
  if(index < ppsNumber.length())
  ch = ppsNumber.charAt(index);
 }

这有一些问题。 while循环确保索引小于PPS编号的长度。由于指数只会下降,它总是会变小。你要检查的最后一个字符是索引0,所以你的循环应该停在这里。

在循环之后,你有这个代码:

if(index == ppsNumber.length()-1)
  System.out.println("You entered a valid PPS number.");

这永远不会成真。到目前为止,您的代码已检查PPS是否合适。 index从6开始,只能变小,因此索引永远不会等于PPS长度减去1。

有几种方法可以解决这个问题。您可以简单地修复您的围栏发布错误并更改该if语句,以确保index一直向下计数。更简单的方法是去掉if语句并像这样调整循环:

for(int i = 0; i <= 6; i++) {
    char ch = ppsNumber.charAt(i);

    if(ch < '0' || ch > '9') {
      System.out.println("You entered an invalid PPS number.");
      return;
    }
}

System.out.println("You entered an invalid PPS number.");

这样,一旦发现错误,你的循环就会存在。如果你完成了循环,那么你通过了 - 不需要额外的检查。

答案 3 :(得分:0)

试试这个:

  if(ppsNumber.charAt(7) >= 'A' && ppsNumber.charAt(7) <= 'Z' && (ppsNumber.legth() =8 || (ppsNumber.charAt(8) >= 'A' && ppsNumber.charAt(8) <= 'Z')))