【问题标题】:get unmatched portion from string java 8从字符串 java 8 中获取不匹配的部分
【发布时间】:2023-04-11 11:57:01
【问题描述】:

我的字符串是“我是 Java 新手 (*)”

我的实际字符串是我是 Java 8 的新手,我将从我的地图中获取一堆键,我需要在这里提取不匹配的部分,即 8

我的最终地图应该包含第一个字符串是键,值是不匹配的部分我将如何在 java 8 中做到这一点

Pattern p =Pattern.compile("I am new to Java (*)");

map= map.entrySet()
        .stream()
        .filter(p -> p.getKey().contains("Java")&&p.getKey().matches("I am new to Java (*)"))
        .collect(Collectors.toMap(p -> p.getKey(), p -> p.getValue()));

我正在使用下面的一个,它坏了,有人可以建议吗?

我想要类似的东西

Map<String, String> result=map.entrySet().stream().filter(k-> k.getKey().matches(test) && k.getKey().contains(test))
        .collect(Collectors.toMap(k->k.getKey(), ::p.matcher().group(1)));

我可以使用两张地图来实现它

Map<String, String> result = new HashMap<>();
map.forEach((k,v)->{
            if(k.contains(test)) {
                while(p.matcher(k).find()) {
                    result.put(k, p.matcher(k).group(1));
                }
            }
        });

但我希望它在一张地图中

【问题讨论】:

  • 你的正则表达式不正确,看起来你想使用I am new to Java (.*)* 是一个量词,它通过指定它应该出现的次数来修改前一个标记;( 不是一个可量化的标记;.,将匹配任何字符,是)
  • 我用 (.*) 还是不行
  • 怎么不工作?是否有错误消息或意外结果?
  • 添加了它@Aaron
  • 您的新地图是使用p.getValue() 作为值创建的,因此您不应期望该值会神奇地成为您的正则表达式捕获的Java 版本号。看起来您的过滤器没问题(尽管第一个条件是多余的:如果您的正则表达式匹配,则密钥显然包含“Java”)但您的收集器需要使用 PatternMatcher 从匹配的文本。

标签: java regex java-8


【解决方案1】:

如果我理解正确(并稍微简化了您的示例):

String test = "I am new to Java 8 ";
String t = "I am new to Java (.*) ";
Map<String, String> map = new HashMap<>();
map.put(test, "value1");
map.put("some", "value2");

Map<String, String> result = map.entrySet()
            .stream()
            .filter(e -> !e.getKey().equals(e.getKey().replaceAll(t, "$1")))
            .collect(Collectors.toMap(
                    e -> e.getKey().replaceAll(t, "$1"),
                    Entry::getValue));

【讨论】:

  • 编辑了上面的问题
  • 编辑了问题@aaron
【解决方案2】:

我会这样做:

Pattern p = Pattern.compile("I am new to Java (.*)");
Predicate<String> regexFilter = p.asPredicate();

Function<String,String> versionExtractor = str -> {
  Matcher m = p.matcher(str);
  if (m.find()) {
    return m.group(1);
  } else {
    throw new IllegalArgumentException("It didn't match !"); // should never happen since we match beforehand
  }
};

Map<String,String> result = inputMap.keySet()
  .stream()
  .filter(regexFilter)
  .collect(Collectors.toMap(Function.identity(), versionExtractor));

如果我没记错的话,您遇到的问题是您无法在单个语句中将您的键映射到您的值,因为您需要先.matches,然后才能.group

我们已经习惯了单行 lambdas(由函数式编程的力量支持),以至于我们有时会忘记它们是普通的旧 Functions 并且它们没有这样的限制。在这里,我使用 {statements} 块定义了我的 lambda,并将该 lambda 影响到一个变量,稍后我可以在流处理中引用该变量。我可以直接在流操作中定义 lambda,或者我也可以在不使用 lambda 表示法的情况下实现 Function

Try it here.

【讨论】:

    猜你喜欢
    • 2018-04-06
    • 2023-03-27
    • 2011-11-15
    • 1970-01-01
    • 2021-11-23
    • 2021-02-09
    • 1970-01-01
    • 2018-02-18
    • 1970-01-01
    相关资源
    最近更新 更多