用于排除特殊字符的正则表达式

时间:2009-04-16 15:04:54

标签: java regex

我无法想出一个正则表达式,它基本上会将某些特殊字符列入黑名单。

我需要使用它来验证输入字段中的数据(在Java Web应用程序中)。我们希望允许用户输入任何数字,字母(我们需要包括重音字符,例如法语或德语)和一些特殊字符,例如' - 。等。

如何将<>%$ etc等字符列入黑名单?

非常感谢任何帮助。

11 个答案:

答案 0 :(得分:36)

我只是将这些字符列入白名单。

^[a-zA-Z0-9äöüÄÖÜ]*$

使用正则表达式构建黑名单同样简单,但您可能需要添加更多字符 - 在unicode中有很多中文符号......;)

^[^<>%$]*$

表达式[^(这里有很多字符)]只匹配未列出的任何字符。

答案 1 :(得分:8)

要排除某些字符(&lt;,&gt;,%和$),您可以制作如下的正则表达式:

[<>%\$]

此正则表达式将匹配其中包含黑名单字符的所有输入。括号定义了一个字符类,并且在美元符号之前是必需的,因为美元符号在正则表达式中具有特殊含义。

要在黑名单中添加更多字符,只需将它们插入括号之间即可;顺序无所谓。

根据一些Java documentation for regular expressions,您可以使用如下表达式:

Pattern p = Pattern.compile("[<>%\$]");
Matcher m = p.matcher(unsafeInputString);
if (m.matches())
{
    // Invalid input: reject it, or remove/change the offending characters.
}
else
{
    // Valid input.
}

答案 2 :(得分:5)

通常情况下,将您允许的字符列入白名单通常会更好,而不是将您不允许的字符列入黑名单。从安全角度和易于实施的角度来看都是如此。

如果您确实进入黑名单路线,这是一个示例,但要注意,语法并不简单。

http://groups.google.com/group/regex/browse_thread/thread/0795c1b958561a07

如果要将所有重音字符列入白名单,可能使用unicode范围会有帮助吗?看看这个链接。

http://www.regular-expressions.info/unicode.html

答案 3 :(得分:4)

我想这取决于您所定位的语言。一般来说,这样的事情应该有效:

[^<>%$]

[]”构造定义了一个字符类,它将匹配任何列出的字符。将“^”作为第一个字符会否定匹配,即:除了列出的其中一个字符之外的任何字符。

您可能需要转义“[]”中的某些字符,具体取决于您使用的语言/正则表达式引擎。

答案 4 :(得分:3)

即使在2009年,似乎有太多人对于为WORLDWIDE网络设计所涉及的内容提出了非常有限的想法。 2015年,除非为特定国家/地区进行设计,否则黑名单是容纳可能有效的大量字符的唯一方式。

然后需要根据需要数据的目的来选择要列入黑名单的字符。

然而,有时需要分解要求,并分别处理每个要求。在这里,展望未来是你的朋友。这些部分由(?=)限制为正数,(?!)为负数,并且实际上成为AND块,因为当处理块时,如果没有失败,正则表达式处理器将从文本的开头开始与下一个块。实际上,每个前瞻块前面都会有^,如果它的模式是贪婪的,则最多包含$。即使是古老的VB6 / VBA(Office)5.5正则表达式引擎也支持前瞻。

因此,要构建完整的正则表达式,请从前瞻块开始,然后在最终$之前添加列入黑名单的字符块。

例如,要限制字符总数(例如3到15之间),请从正向预测块(?=^.{3,15}$)开始。请注意,这需要自己的^$,以确保它涵盖了所有文字。

现在,虽然您可能希望允许_和 - ,但您可能不希望以它们开头或结尾,因此添加两个负面预测块,(?![_-].+)表示开始,(?!.+[_-]$)为了目的。

如果您不想要多个_-,请添加(?!.*[_-]{2,})的否定预测块。这也将排除_--_序列。

如果没有更多的前瞻块,则在$之前添加黑名单块,例如[^<>[\]{\}|\\\/^~%# :;,$%?\0-\cZ]+,其中\0-\cZ排除null和控制字符,包括NL( \n)和CR(\r)。最终+确保贪婪地包含所有文本。

在Unicode域中,可能还需要排除其他代码点或块,但肯定比必须包含在白名单中的所有块少得多。

所有上述的整个正则表达式将是

(?=^.{3,15}$)(?![_-].+)(?!.+[_-]$)(?!.*[_-]{2,})[^<>[\]{}|\\\/^~%# :;,$%?\0-\cZ]+$

你可以在https://regex101.com/上查看,pcre(php),javascript和python正则表达式引擎。我不知道java正则表达式适用于哪些,但您可能需要修改正则表达式以满足其特性。

如果你想要包含空格,而不是_,只需在正则表达式中的每个位置交换它们。

此技术最有用的应用是针对HTML pattern字段的input属性,其中需要单个表达式,为失败返回false,从而使字段无效,允许input:invalid 1}} css突出显示它,并停止提交的表单。

答案 5 :(得分:2)

你真的想将特定字符列入黑名单,还是将允许的字符列入白名单?

我认为你真的想要后者。这非常简单(将任何其他符号添加到[\-]组的白名单中):

^(?:\p{L}\p{M}*|[\-])*$

编辑:使用评论

的输入优化模式

答案 6 :(得分:2)

否定的一切不是字母数字和&amp; ASCII字符的下划线:

/[^\W]/g

对于电子邮件或用户名验证,我使用了以下允许4个标准特殊字符的表达式 - _。 @

/^[-.@_a-z0-9]+$/gi

对于严格的仅限字母数字的表达式,请使用:

/^[a-z0-9]+$/gi

测试@ RegExr.com

答案 7 :(得分:1)

为什么你认为正则表达式是最好的工具?如果您的目的是检测字符串中是否存在非法字符,那么测试循环中的每个字符将比构造正则表达式更简单,更有效。

答案 8 :(得分:1)

以下是所有法语口音字符: àÀâÂäÄáÁéÉèÈêÊëËìÌîÎïÏòÒôÔöÖùÙûÛüÜçÇ'ñ

我会谷歌一个德国重音字符列表。没有那么多。你应该能够得到它们。

对于URLS我用如下常规字母替换带重音的URL:

string beforeConversion = "àÀâÂäÄáÁéÉèÈêÊëËìÌîÎïÏòÒôÔöÖùÙûÛüÜçÇ’ñ";
string afterConversion = "aAaAaAaAeEeEeEeEiIiIiIoOoOoOuUuUuUcC'n";
for (int i = 0; i < beforeConversion.Length; i++) {

     cleaned = Regex.Replace(cleaned, beforeConversion[i].ToString(), afterConversion[i].ToString());
}

请注意,可能有一种更有效的方法。

答案 9 :(得分:1)

使用此

^(?= [a-zA-Z0-9~ @#$ ^ ()_ + = [] {} | \,。?: - ] $)(?!。 * [&LT;&GT;&#39;&#34; /;`%])

答案 10 :(得分:0)

我强烈怀疑能够更容易地得到允许的字符列表与不存在的字符列表 - 一旦你有了这个列表,正则表达式语法变得非常简单。所以把我当作另一个投票给“白名单”。