【问题标题】:Validate a String (PPS number)验证字符串(PPS 编号)
【发布时间】:2013-12-21 13:33:39
【问题描述】:

好的,我正在尝试验证字符串(在本例中为 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();
    }
}

【问题讨论】:

  • if/else 中使用大括号,这样会让人困惑
  • 在您的 while 循环中,您正在检查索引
  • @Gayathri 我也试过了。它在某些情况下有效,但并非适用于所有情况。
  • 你能具体说明它失败的情况吗?
  • 你也可以考虑在 if((ppsNumber.charAt(7) >= 'A' && ppsNumber.charAt(7) = 'A' && ppsNumber.charAt(8)

标签: java string loops


【解决方案1】:

存在多个问题。我发现的第一个是这样的:

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.");

这是一个超出范围的字符串索引,因为您检查了index &lt;,但您正在递减。应该是这样的:

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 (/*    */) {

    }
}

二选一。

如果您以后提出问题,您还应该描述您遇到的具体问题,而不仅仅是“无法正常工作”。 “不起作用”并没有告诉我们任何有关如何提供帮助的信息,而且有些人相当不愿意或无法运行该程序。特别是当涉及异常之类的东西时。发布堆栈跟踪并指出引发错误的行。至少应该清楚地包括有一个例外以及什么样的例外。

【讨论】:

  • 这适用于所有情况,除非我将输入设置为 1234567Pk,它给了我一个有效的 PPS。
  • 检查最后 1 位或 2 位数字的 if 条件存在问题。 || 应该是 &amp;&amp;。检查长度的必要性也很复杂,但我更新了我的答案以显示一个同时进行的表达式。
【解决方案2】:

试试这个:

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

【讨论】:

    【解决方案3】:

    这与您的 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 长度减一。

    有几种方法可以解决此问题。您可以简单地修复您的栅栏发布错误并更改该 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.");
    

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

    【讨论】:

      【解决方案4】:

      对于这些类型的问题,我更喜欢正则表达式。

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

      【讨论】:

      • 您不应该在正则表达式的开头添加^ 并在末尾添加$ 吗?
      • 我知道正则表达式是救命稻草,但不幸的是,我不允许在这种情况下使用正则表达式。 :(
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-21
      相关资源
      最近更新 更多