在java正则表达式中组合白名单和黑名单

我在构造正则表达式时遇到问题,该正则表达式将允许除2个字符外的全部UTF-8字符:’_’和’?’

所以白名单是:^ [\ u0000- \ uFFFF],黑名单是:^ [^ _%]

我需要将它们组合成一个表达式。

我尝试了以下代码,但是没有按照我希望的方式工作:

String input = "this"; Pattern p = Pattern .compile("^[\u0000-\uFFFF]+$ | ^[^_%]"); Matcher m = p.matcher(input); boolean result = m.matches(); System.out.println(result); 

输入:这个
实际输出:false
期望的输出:true

您可以在Java regex中使用字符类交叉/减法来限制“通用”字符类。

字符类[az&&[^aeiuo]]匹配不是元音的单个字母。 换句话说:它匹配单个辅音。

使用

 "^[\u0000-\uFFFF&&[^_%]]+$" 

匹配除_%之外的所有Unicode字符。

有关Java正则表达式中可用的字符类交叉/减法的更多信息,请参阅Java™教程:字符类

在OCPSoft Visual Regex Tester上进行测试,显示在将%添加到字符串时没有匹配:

在此处输入图像描述

和Java演示 :

 String input = "this"; Pattern p = Pattern.compile("[\u0000-\uFFFF&&[^_%]]+"); // No anchors because `matches()` is used Matcher m = p.matcher(input); boolean result = m.matches(); System.out.println(result); // => true 

下面是一个示例代码,用于使用Lookahead和Lookbehind Zero-Length Assertions从一个范围中排除某些字符,这些字符实际上不消耗字符串中的字符,但只断言是否可以匹配。

示例代码:(从范围az排除mn

  String str = "abcdmnxyz"; Pattern p=Pattern.compile("(?![mn])[az]"); Matcher m=p.matcher(str); while(m.find()){ System.out.println(m.group()); } 

输出:

 abcdxyz 

以同样的方式你可以做到。

正则表达式解释(?![mn])[az]

  (?! look ahead to see if there is not: [mn] any character of: 'm', 'n' ) end of look-ahead [az] any character of: 'a' to 'z' 

您可以在子范围内划分整个范围,也可以用([al]|[oz])[a-lo-z]正则表达式解决上述问题。

你的问题是管道两侧的空间。

两者都没有

 " ^.*" ".*$ " 

将匹配任何内容,因为在开始或结束之前没有任何内容。

这有机会:

 ^[\u0000-\uFFFF]+$|^[^_%]