Java 8 如何使用regexp和谓词筛选()流方法以获得否定列表

Java 8 如何使用regexp和谓词筛选()流方法以获得否定列表,java-8,java-stream,Java 8,Java Stream,我正在尝试筛选任何不在regexp中的内容。 所以我想表达的是,在一个列表中写入除a-z、0-9和-,以外的任何字符,这样我就可以在之后用无效字符处理这些城市名称。 但是无论我尝试什么,我要么得到一个有效城市的列表,要么得到一个非法的argumentexception,其中列表包含有效的字符城市 String str; List<String> invalidCharactersList = cityName.stream() .filter(Pa

我正在尝试筛选任何不在regexp中的内容。 所以我想表达的是,在一个列表中写入除a-z、0-9和-,以外的任何字符,这样我就可以在之后用无效字符处理这些城市名称。 但是无论我尝试什么,我要么得到一个有效城市的列表,要么得到一个非法的argumentexception,其中列表包含有效的字符城市

 String str;

    List<String> invalidCharactersList = cityName.stream()
            .filter(Pattern.compile("[^a-z0-9-]*$").asPredicate())
            .collect(toList());

    // Check for invalid names
    if (!invalidCharactersList.isEmpty()) {
        str = (inOut) ? "c" : "q";
        throw new IllegalArgumentException("City name characters "
                + str + ": for city name " + invalidCharactersList.get(0)
                + ": fails constraint city names [a-z, 0-9, -]");
    }
String-str;
列表invalidCharactersList=cityName.stream()
.filter(Pattern.compile(“[^a-z0-9-]*$”).asPredicate())
.collect(toList());
//检查无效名称
如果(!invalidCharactersList.isEmpty()){
str=(inOut)?“c”:“q”;
抛出新的IllegalArgumentException(“城市名称字符”
+str+“:对于城市名称“+invalidCharactersList.get(0)
+“:城市名称[a-z,0-9,-]”;
}
我正在尝试筛选任何不在regexp中的内容

下面是一些在第一个列表中失败的测试数据,我希望它在最后一个列表中失败

List<String> c = new ArrayList<>(Arrays.asList("fastcity", "bigbanana", "xyz"));
List<Integer> x = new ArrayList<>(Arrays.asList(23, 23, 23));
List<Integer> y = new ArrayList<>(Arrays.asList(1, 10, 20));
List<String> q = new ArrayList<>(Arrays.asList("fastcity*", "bigbanana", "xyz&"));
List c=newarraylist(Arrays.asList(“fastcity”、“bigbanana”、“xyz”);
List x=新的ArrayList(Arrays.asList(23,23,23));
列表y=新的ArrayList(Arrays.asList(1,10,20));
List q=新的ArrayList(Arrays.asList(“fastcity*”、“bigbanana”、“xyz&”);
以下是输出:

霍尔格

filter(Pattern.compile("[^a-z0-9-]").asPredicate())

谢谢,这很好。

.filter(Pattern.compile(“^[a-z0-9-]+$”).asPredicate().negate())
列表中查找无效字符毫无意义。此外,在任意元素未通过测试时报告第一个列表元素可能会非常混乱。除此之外,它还可以像过滤(Pattern.compile(“[^a-z0-9-]”)一样简单;当除a-z、0-9和-以外的任何字符存在时,这将通过。我希望它在最后失败。你说的“你希望它失败”是什么意思?您正在筛选
列表
。你想过滤掉某些
元素,对吗?因此,在过滤最后一个
列表
之后,过滤后的
列表
将只包含一个元素,即bigbanana。是这样吗?@Abra我希望列表只包含xyz&as&是无效的。我不想挑剔这一点,但对于
fastcity\nbigbanana\nxyz\nfastcity*\nbigbanana\nxyz&
^[a-z0-9-]+$
的输入,它需要36个步骤,而
[^a-z0-9-]
需要55个步骤才能完成。@AniketSahrawat你的评论毫无意义。您是否真的在谈论带换行符的输入,什么是“步骤”,以及您是如何测量的?使用,您可以看到
[^a-z0-9-]
需要更少的操作。由于测试程序打印引擎读取的字符,您也可以看到原因。当遇到无效字符时,模式
^[a-z0-9-]+$
将尝试匹配锚定和回溯。您可以使用
^[a-z0-9-]+$
消除回溯,这将缩短间距,但在无效字符处仍有一个锚测试访问权限。但出于任何实际目的,这两种方法之间没有相关的区别。@Holger使用和输出程序。这是一个明显的区别,但即使你知道这不是一个标准的方式。我最初是在PCRE上测试的。无论如何,我不会对此进行进一步的争论,正如您在第二次评论的最后一句中所提到的那样。@AniketSahrawat我不知道有什么“标准方法”来检查这一点,并提供了一种测试引擎实际运行情况的方法。无论如何,对于JDK16,这似乎是一个有趣的性能回归,我将对此进行调查(并可能提交一份bug报告)。