如果字符串包含非法字符,则返回Java函数

时间:2013-01-31 21:22:55

标签: java regex string

我有以下字符,我希望被视为“非法”:

~#@*+%{}<>[]|\,{ {1}},_

我想编写一个检查字符串并确定(^ / true)的方法,如果该字符串包含这些非法行为:

false

但是,对此进行简单的public boolean containsIllegals(String toExamine) { return toExamine.matches("^.*[~#@*+%{}<>[]|\"\\_^].*$"); } 检查是不可行的。我需要方法来扫描字符串中的每个字符,并确保它不是这些字符之一。当然,我可以做一些可怕的之类的事情:

matches(...)

是否有更优雅/更有效的方法来实现这一目标?

6 个答案:

答案 0 :(得分:27)

您可以在此处使用PatternMatcher课程。您可以将所有已过滤的字符放在字符类中,并使用Matcher#find()方法检查您的模式是否以字符串形式提供。

你可以这样做: -

public boolean containsIllegals(String toExamine) {
    Pattern pattern = Pattern.compile("[~#@*+%{}<>\\[\\]|\"\\_^]");
    Matcher matcher = pattern.matcher(toExamine);
    return matcher.find();
}
如果在字符串中找到给定的模式,

find()方法将返回true,甚至一次。


尚未指出的另一种方法是使用String#split(regex)。我们可以在给定模式上拆分字符串,并检查数组的长度。如果length为1,则模式不在字符串中。

public boolean containsIllegals(String toExamine) {
    String[] arr = toExamine.split("[~#@*+%{}<>\\[\\]|\"\\_^]", 2);
    return arr.length > 1;
}

如果arr.length > 1,这意味着字符串包含模式中的一个字符,这就是它被拆分的原因。我已将limit = 2作为第二个参数传递给split,因为我们只需单次拆分即可。

答案 1 :(得分:11)

  

我需要方法来扫描字符串中的每个字符

如果你必须逐个字符地进行,那么regexp可能不是一个好方法。但是,由于“黑名单”中的所有字符都具有小于128的代码,因此您可以使用小boolean数组执行此操作:

static final boolean blacklist[] = new boolean[128];

static {
    // Unassigned elements of the array are set to false
    blacklist[(int)'~'] = true;
    blacklist[(int)'#'] = true;
    blacklist[(int)'@'] = true;
    blacklist[(int)'*'] = true;
    blacklist[(int)'+'] = true;
    ...
}

static isBad(char ch) {
    return (ch < 128) && blacklist[(int)ch];
}

答案 2 :(得分:8)

如果你不能使用匹配器,那么你可以做这样的事情,它比一堆不同的if语句或字节数组更清晰。

 for(int i = 0; i < toExamine.length(); i++) {
    char c = toExamine.charAt(i);
    if("~#@*+%{}<>[]|\"_^".contains(c)){
         return true;
    }
 }

答案 3 :(得分:8)

使用常量来避免在每次验证中重新编译正则表达式。

private static final Pattern INVALID_CHARS_PATTERN = 
                               Pattern.compile("^.*[~#@*+%{}<>\\[\\]|\"\\_].*$");

并将您的代码更改为:

public boolean containsIllegals(String toExamine) {
    return INVALID_CHARS_PATTERN.matcher(toExamine).matches();
}

这是Regex最有效的方式。

答案 4 :(得分:5)

尝试否定包含所有列入黑名单的字符类:

public boolean containsIllegals(String toExamine) {
    return toExamine.matches("[^~#@*+%{}<>\\[\\]|\"\\_^]*");
}

如果字符串包含非法字符,则返回true(在这种情况下,您的原始函数似乎返回false。)

开头括号^右侧的插入符号[否定了字符类。请注意,在String.matches()中,您不需要锚点^$,因为它会自动匹配整个字符串。

答案 5 :(得分:2)

执行此操作的一种非常紧凑的方法是依赖String.replaceAll方法:

public boolean containsIllegal(final String toExamine) {
    return toExamine.length() != toExamine.replaceAll(
            "[~#@*+%{}<>\\[\\]|\"\\_^]", "").length();
}