正则表达式测试失败 - Java

6

我正在尝试执行一个简单的正则表达式。本质上,我想确定我的字符串中是否有特殊字符,如果有,就检查字符串的每个字符是否具有两个特定的字符,即连字符和句点。

我似乎在第一部分遇到了问题,这部分涉及确定我的字符串中是否有特殊字符。

以下是我尝试使用的方法,后面是我遇到问题的字符串:

public static boolean stringValidity(String input) {
    int specials = 0;

    Pattern p = Pattern.compile("[^a-zA-Z0-9 ]");
    Matcher m = p.matcher(input);
    boolean b = m.find();

    if (b) {
        System.out.println("\nstringValidity - There is a special character in my string");

        for (int i = 0; i < input.length(); ++i) {

           char ch = input.charAt(i);

           //if (!Character.isDigit(ch) && !Character.isLetter(ch) && !Character.isSpace(ch)) {
              ++specials;

              System.out.println("\nstringValidity - Latest number of special characters is: " + specials);

              if((ch == '-') | (ch == '.')) {
                  specialCharValidity = true;

                  System.out.println("\nstringValidity - CHAR is valid - specialCharValidity is: " + specialCharValidity + " as char is: " + ch);
              } else {
                  specialCharValidity = false;

                  System.out.println("\nstringValidity - CHAR is invalid - specialCharValidity is: " + specialCharValidity + " as char is: " + ch);

                  break;
              }
           //}
        }
    } else {
        System.out.println("\nstringValidity - There is NO special character in my string");

        specialCharValidity = true;
    }

    return specialCharValidity;
}

以下是我传递给方法的字符串,我期望它们被视为带有特殊字符的字符串,但测试失败了:

"QWERTY"!£$"£$"
"sdfGSDFGSDFG%*^(%*&("

以下是我传递给该方法的字符串,我原以为它们不会被视为带特殊字符的字符串,但测试失败了:
"QWE12342134RTY"
"LOREMIPSUM2354214"

非常感谢您的提议和建议,我们将认真考虑并加以采纳。


对我来说没问题... Pattern.compile("[^a-zA-Z0-9 ]").matcher("sdfGSDFGSDFG%^(%&(").find() 返回 truePattern.compile("[^a-zA-Z0-9 ]").matcher("QWE12342134RTY").find() 返回 false - Dima
如果您取消注释已注释的行,则该函数就能正常工作。 - Salman A
@Dima和Salaman:取消if语句的注释并将模式更改为[^a-zA-Z0-9 \-\.]后,它可以工作。感谢您的建议。 - TokTok123
2个回答

1
你可以通过检查字符串是否符合以下模式来简化你的代码:
[^a-zA-Z0-9 \-\.]

字符串有效性函数可以归结为:

public static boolean stringValidity(String input) 
{
    return Pattern.compile("[^a-zA-Z0-9 \\-\\.]").matcher(input).find() == false;
}

0

使用提供的字符串运行您的代码,我得到了以下输出:

stringValidity - There is a special character in my string

stringValidity - Latest number of special characters is: 1

stringValidity - CHAR is invalid - specialCharValidity is: false as char is: Q
---

stringValidity - There is a special character in my string

stringValidity - Latest number of special characters is: 1

stringValidity - CHAR is invalid - specialCharValidity is: false as char is: s
---

stringValidity - There is NO special character in my string
---

stringValidity - There is NO special character in my string
---

我猜这意味着你用于查找特殊字符(不是数字或字母)的模式没有问题。但是我发现你的代码存在以下问题:

  1. 确保正确将那些字符串作为参数传递。在您的程序中,列表中的第一个字符串应该声明为“QWERTY\”!£$\"£$”,因为Java要求在字符串内部使用双引号时必须在其前面加上反斜杠,以免被解释为字符串分隔符;
  2. 您测试的第二部分不起作用,因为您只测试了字符串中的第一个字符。您的逻辑是这样说的:“如果当前字符是点或连字符,则specialCharValidity = true,否则(如果它是任何其他无效或有效的字符而不是点和连字符)只需使specialCharValidity = false并退出循环”。奇怪的是,您已经做对了:只需重新启用您已注释的行以列出适当的无效字符即可。如果您想启用specials的计数,只需删除带有break的行,以便循环不会在第一个特殊字符处停止;

一些建议

  • Character.isSpace()替换为Character.isWhitespace(),因为第一个版本已经被弃用;
  • 在本地定义specialCharValidity以避免潜在问题;
  • 为了性能考虑,不要在每次调用时编译相同的模式,就像你在Pattern p = Pattern.compile("[^a-zA-Z0-9 ]");中所做的那样。编译模式是耗费时间的,因此您可以在类顶部定义一个常量,如static public final Pattern p = Pattern.compile("[^a-zA-Z0-9 ]");,并稍后使用它;
  • 模式是匹配复杂字符串模式的绝佳工具,但在这种情况下有些过度了。如果你只需要匹配/查找这样的字符,最好只进行字符比较,因为模式会增加不必要的开销。

感谢您的回复。我再次尝试了我的代码,但将模式更改为“[^a-zA-Z0-9 \-\.]”,而不是“[^a-zA-Z0-9]”。基本上,根据ulix的回复,取消注释我放置的检查,即isDigit(),isLetter()和isWhiteSpace(),使我能够测试第一个字符之后的内容。我使用我在原始帖子中提到的字符串进行了测试。此外,我非常感谢您额外的建议,我已经实施并让代码变得更加清晰。 - TokTok123

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接