提问人: 提问时间:4/16/2009 最后编辑:TylerH 更新时间:10/15/2023 访问量:316352
用于排除特殊字符的正则表达式 [已关闭]
Regular expression for excluding special characters [closed]
问:
我在想出一个正则表达式时遇到了麻烦,该表达式基本上会将某些特殊字符列入黑名单。
我需要使用它来验证输入字段中的数据(在 Java Web 应用程序中)。我们希望允许用户输入任何数字、字母(我们需要包括重音字符,例如法语或德语)和一些特殊字符,例如“-”。等。
如何将 <>%$ 等字符列入黑名单?
答:
通常最好将允许的字符列入白名单,而不是将不允许的字符列入黑名单。无论是从安全性的角度,还是从易于实施的角度来看。
如果你确实走黑名单路线,这里有一个例子,但请注意,语法并不简单。
http://groups.google.com/group/regex/browse_thread/thread/0795c1b958561a07
如果您想将所有重音字符列入白名单,也许使用 unicode 范围会有所帮助?查看此链接。
http://www.regular-expressions.info/unicode.html
评论
您真的想将特定字符列入黑名单,还是将允许的字符列入白名单?
我假设你真的想要后者。这很简单(将任何其他符号添加到组中的白名单):[\-]
^(?:\p{L}\p{M}*|[\-])*$
编辑:使用注释中的输入优化了模式
评论
matches()
我只会将角色列入白名单。
^[a-zA-Z0-9äöüÄÖÜ]*$
使用正则表达式构建黑名单同样简单,但您可能需要添加更多字符 - unicode 中有很多中文符号...... ;)
^[^<>%$]*$
表达式 [^(此处有许多字符)] 仅匹配未列出的任何字符。
评论
我想这取决于你针对的语言。一般来说,这样的事情应该有效:
[^<>%$]
“” 构造定义一个字符类,该类将与列出的任何字符匹配。将“”作为第一个字符将否定匹配,即:列出的字符之一以外的任何字符。[]
^
您可能需要对 “” 中的某些字符进行转义,具体取决于您使用的语言/正则表达式引擎。[]
我强烈怀疑,列出允许的字符和不允许的字符列表会更容易——一旦你有了这个列表,正则表达式语法就变得非常简单了。所以把我作为“白名单”的另一票。
要排除某些字符(<、>、% 和 $),您可以创建如下所示的正则表达式:
[<>%\$]
此正则表达式将匹配所有包含黑名单字符的输入。括号定义一个字符类,\ 在美元符号之前是必需的,因为美元符号在正则表达式中具有特殊含义。
要向黑名单添加更多字符,只需将它们插入括号之间即可;顺序无关紧要。
根据一些正则表达式的 Java 文档,您可以像这样使用表达式:
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.
}
评论
为什么您认为正则表达式是最好的工具?如果您的目的是检测字符串中是否存在非法字符,则测试循环中的每个字符将比构造正则表达式更简单、更高效。
评论
以下是所有法语重音字符: àÀâÂäÄáÁéÉèÈêÊëËÌÌîÎïÏòÒôÔöÖùÛÛüÜçÇ'ñ
我会在谷歌上搜索德语重音字符列表。没有那么多。你应该能够得到它们。
对于 URL,我将重音 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());
}
请注意,可能还有一种更有效的方法。
评论
即使在 2009 年,似乎也有太多人对万维网的设计内容非常有限。在 2015 年,除非针对特定国家/地区进行设计,否则黑名单是容纳大量可能有效的字符的唯一方法。
然后,需要根据需要数据的目的选择要列入黑名单的字符。
但是,有时分解需求并单独处理每个需求是值得的。在这里,向前看是你的朋友。这些是以正和负为边界的部分,实际上成为 AND 块,因为当处理块时,如果没有失败,正则表达式处理器将从文本的开头开始下一个块。实际上,每个 look-ahead 块前面都会有 ,如果其模式是贪婪的,则最多包括 。即使是古老的 VB6/VBA (Office) 5.5 正则表达式引擎也支持前瞻。(?=)
(?!)
^
$
因此,要构建一个完整的正则表达式,请从前瞻块开始,然后在最终的 .$
例如,要限制字符总数(包括 3 到 15 个字符),请从 positive look-ahead 块开始。请注意,这需要它自己的,并确保它涵盖所有文本。(?=^.{3,15}$)
^
$
现在,虽然您可能希望允许 _ 和 -,但您可能不希望以它们开头或结尾,因此请添加两个否定的 look-ahead 块,分别用于 start 和 ends。(?!^[_-].+)
(?!.+[_-]$)
如果不需要多个 和 ,请添加负前瞻块 。这也将排除 和 序列。_
-
(?!.*[_-]{2,})
_-
-_
如果没有更多的前瞻块,则在 之前添加黑名单块,例如 ,其中排除 null 和控制字符,包括 NL () 和 CR ()。最后确保所有文本都被贪婪地包含在内。$
[^<>[\]{\}|\\\/^~%# :;,$%?\0-\cZ]+
\0-\cZ
\n
\r
+
在Unicode域中,可能还需要排除其他代码点或块,但肯定比必须包含在白名单中的所有块要少得多。
然后,上述所有内容的整个正则表达式将是
(?=^.{3,15}$)(?!^[_-].+)(?!.+[_-]$)(?!.*[_-]{2,})[^<>[\]{}|\\\/^~%# :;,$%?\0-\cZ]+$
您可以在 https://regex101.com/ 上实时查看 PCRE (PHP)、JAVASCRIPT 和 Python 正则表达式引擎。我不知道 java 正则表达式适合其中的位置,但您可能需要修改正则表达式以迎合其特性。
如果要包含空格,但不想包含空格,只需在正则表达式中的每个位置交换它们即可。_
这种技术最有用的应用是HTML字段的属性,其中需要单个表达式,如果失败,则返回false,从而使字段无效,允许css突出显示它,并停止提交表单。请注意,属性中的任何隔离(不在范围内)都必须具有前面才能对其进行转义。pattern
input
input:invalid
-
pattern
\
评论
使用这个
^(?=[a-zA-Z0-9~@#$^*()_+=[\]{}|\\,.?: -]*$)(?!.*[<>'"/;`%])
ASCII 字符的非字母数字和下划线的否定集合:
/[^\W]/g
对于电子邮件或用户名验证,我使用了以下表达式,该表达式允许 4 个标准特殊字符 - _ .@
/^[-.@_a-z0-9]+$/gi
对于严格的仅字母数字表达式,请使用:
/^[a-z0-9]+$/gi
测试 @ RegExr.com
评论
\w
\W
-
[]
-
[]
/[^\W]/
á
\p{Ll}\p{M}*
\p{N}
\p{L}\p{M}*
评论