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

IAm*_*aja 20 java regex string

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

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

我想编写一个检查字符串的方法,并确定(true/ false)该字符串是否包含这些非法字符:

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

但是,matches(...)对此进行简单检查是不可行的.我需要该方法来扫描字符串中的每个字符,并确保它不是这些字符之一.当然,我可以做一些可怕的事情:

public boolean containsIllegals(String toExamine) {
    for(int i = 0; i < toExamine.length(); i++) {
        char c = toExamine.charAt(i);

        if(c == '~')
            return true;
        else if(c == '#')
            return true;

        // etc...
    }
}
Run Code Online (Sandbox Code Playgroud)

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

Roh*_*ain 28

你可以在这里使用PatternMatcher上课.您可以将所有已过滤的字符放在字符类中,并使用Matcher#find()方法检查您的模式是否在字符串中可用.

你可以这样做: -

public boolean containsIllegals(String toExamine) {
    Pattern pattern = Pattern.compile("[~#@*+%{}<>\\[\\]|\"\\_^]");
    Matcher matcher = pattern.matcher(toExamine);
    return matcher.find();
}
Run Code Online (Sandbox Code Playgroud)

find() 如果在字符串中找到给定的模式,则方法将返回true,甚至一次.


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

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

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


das*_*ght 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];
}
Run Code Online (Sandbox Code Playgroud)


Pau*_*gas 9

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

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

并将您的代码更改为:

public boolean containsIllegals(String toExamine) {
    return INVALID_CHARS_PATTERN.matcher(toExamine).matches();
}
Run Code Online (Sandbox Code Playgroud)

这是Regex最有效的方法.


Pet*_*ott 8

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

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


Rei*_*ard 5

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

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

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

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