如果字符串包含非法字符,则返回Java函数
我有以下字符,我希望被视为“非法”:
~
, #
, @
, *
, +
, %
, {
, }
, <
, >
, [
, ]
, |
, “
, ”
, \
, _
, ^
我想编写一个检查字符串的方法,并确定( true
/ false
)该字符串是否包含这些非法字符:
public boolean containsIllegals(String toExamine) { return toExamine.matches("^.*[~#@*+%{}[]|\"\\_^].*$"); }
但是,简单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... } }
是否有更优雅/有效的方法来实现这一目标?
您可以在此处使用Pattern
和Matcher
类。 您可以将所有已过滤的字符放在字符类中,并使用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
第二个参数,因为我们只需单个拆分即可。
我需要该方法来扫描字符串中的每个字符
如果你必须按字符逐个进行,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]; }
如果您不能使用匹配器,那么您可以执行类似这样的操作,它比一堆不同的if语句或字节数组更清晰。
for(int i = 0; i < toExamine.length(); i++) { char c = toExamine.charAt(i); if("~#@*+%{}<>[]|\"_^".contains(c)){ return true; } }
使用常量来避免在每次validation中重新编译正则表达式。
private static final Pattern INVALID_CHARS_PATTERN = Pattern.compile("^.*[~#@*+%{}<>\\[\\]|\"\\_].*$");
并将您的代码更改为:
public boolean containsIllegals(String toExamine) { return INVALID_CHARS_PATTERN.matcher(toExamine).matches(); }
这是Regex最有效的方法。
尝试否定包含所有列入黑名单的字符的字符类:
public boolean containsIllegals(String toExamine) { return toExamine.matches("[^~#@*+%{}<>\\[\\]|\"\\_^]*"); }
如果字符串包含非法字符,则返回true
(在这种情况下,您的原始函数似乎返回false
)。
插入符号^
位于左括号的右侧[
否定字符类别。 请注意,在String.matches()
您不需要锚点^
和$
因为它会自动匹配整个字符串。
一个非常紧凑的方法是依赖String.replaceAll
方法:
public boolean containsIllegal(final String toExamine) { return toExamine.length() != toExamine.replaceAll( "[~#@*+%{}<>\\[\\]|\"\\_^]", "").length(); }