Java 删除放置在其他正则表达式匹配中的正则表达式匹配

Java 删除放置在其他正则表达式匹配中的正则表达式匹配,java,regex,Java,Regex,我有两个正则表达式。我想删除第二个的所有匹配项,如果它们放在第一个的匹配项中。基本上,在已经匹配的内容中没有任何内容可以匹配。例如: 第一个正则表达式(粗体)c\w+查找以c 第二个正则表达式(带下划线)me查找me 结果:cam̲e̲l crim̲e̲care coolm̲e̲dium m̲e̲lt hom̲e̲ c字中的me也匹配。我想要的是:骆驼犯罪护理酷m̲e̲dium m̲e̲lt hom̲e̲ 第二个正则表达式的两个结果是第一个正则表达式的结果,我想删除它们,或者根本不匹配它们。以下

我有两个正则表达式。我想删除第二个的所有匹配项,如果它们放在第一个的匹配项中。基本上,在已经匹配的内容中没有任何内容可以匹配。例如:

第一个正则表达式(粗体)c\w+查找以
c

第二个正则表达式(带下划线)me查找
me

结果:cam̲e̲l crim̲e̲care coolm̲e̲dium m̲e̲lt hom̲e̲

c字中的
me
也匹配。我想要的是:骆驼犯罪护理酷m̲e̲dium m̲e̲lt hom̲e̲

第二个正则表达式的两个结果是第一个正则表达式的结果,我想删除它们,或者根本不匹配它们。以下是我尝试过的:

String text = "camel crime care cool medium melt home";

static final Pattern PATTERN_FIRST = Pattern.compile("c\w+");
static final Pattern PATTERN_SECOND = Pattern.compile("me");

// Save all matches
List<int[]> firstRegexMatches = new ArrayList<>();
for (Matcher m = PATTERN_FIRST.matcher(text); m.find();) {
    firstRegexMatches.add(new int[]{m.start(), m.end()}); 
}

List<int[]> secondRegexMatches = new ArrayList<>();
for (Matcher m = PATTERN_SECOND.matcher(text); m.find();) { 
    secondRegexMatches.add(new int[]{m.start(), m.end()}); 
}

// Remove matches of second inside matches of first
for (int[] pos : firstRegexMatches) {
        Iterables.removeIf(secondRegexMatches, p -> p[0] > pos[0] && p[1] < pos[1]);
}
String text=“骆驼犯罪护理冷媒融家”;
静态最终模式Pattern\u FIRST=Pattern.compile(“c\w+”);
静态最终模式Pattern_SECOND=Pattern.compile(“me”);
//保存所有匹配项
List firstRegexMatches=new ArrayList();
for(Matcher m=PATTERN_FIRST.Matcher(text);m.find();){
添加(新的int[]{m.start(),m.end()});
}
List secondRegexMatches=new ArrayList();
for(Matcher m=PATTERN_SECOND.Matcher(text);m.find();){
添加(新的int[]{m.start(),m.end()});
}
//从第一个的匹配项中删除第二个的匹配项
对于(int[]pos:firstRegexMatches){
removeIf(secondRegexMatches,p->p[0]>pos[0]&p[1]
在这段代码中,我将两者的所有匹配项存储到列表中,然后尝试从第一个列表匹配项中的第二个列表删除匹配项


这不仅不起作用,而且我不确定它是否非常有效。请注意,这是我的情况的简化版本,其中包含更多正则表达式和一个大文本。Iterables来自番石榴。

难道不能将这两个正则表达式组合起来吗?例如,
c
之后的
me
可以使用一个带有此代码的正则表达式找到:

((?<=c)|(?<=c\w)|(?<=c\w{2})|(?<=c\w{3})|(?<=c\w{4})|(?<=c\w{5}))me

((?首先,您可以通过将两个表达式合并为一个来实现类似的功能

(^c\w+)|\s(c\w+)|(\w*me\w*)
如果您与此正则表达式匹配,则每个匹配都将是一个以“c”开头的单词,后跟一些单词字符,或者是一个包含“me”的单词。对于每个匹配,您将获得组: (1) 或(2)表示以“c”开头的单词,或 (3) 表示包含“我”的单词

但是请注意,这仅在您知道单词的分隔符(在本例中为\s字符)的情况下有效

示例代码:

    String text = "camel crime care cool medium melt home";

    final Pattern PATTERN = Pattern.compile("(^c\\w+)|\\s(c\\w+)|(\\w*me\\w*)");

    // Save all matches
    List<String> wordsStartingWithC = new ArrayList<>();
    List<String> wordsIncludingMe = new ArrayList<>();

    for (Matcher m = PATTERN.matcher(text); m.find();) {
        if(m.group(1) != null) {
            wordsStartingWithC.add(m.group(1));
        } else if(m.group(2) != null) {
            wordsStartingWithC.add(m.group(2));
        } else if(m.group(3) != null) {
            wordsIncludingMe.add(m.group(3));
        }
    }

    System.out.println(wordsStartingWithC);
    System.out.println(wordsIncludingMe);
然后,您只需对所有这些进行迭代

for(String word: words) {                
    if(word.startsWith("c")) {
        // put in your list for words starting with "c"
    } else if (word.contains("me")) {
        // put in your list for words containing "me"
    }
}

这将导致两个列表没有重复条目,因为第二个if语句只有在第一个语句失败时才会执行。

我不清楚您要做什么。您是否试图从字符串中删除它们,以便结果是
“cal cri care cool medium melt home”
?如果是这样,你的问题就不清楚了。此外,我没有看到任何代码实际上从字符串中删除任何内容。还有,
Iterables
?它不在标准Java库中,那么它是什么?Apache?Guava?如果没有这些信息,我说不出发生了什么,但看起来你的
removeIf
正在删除其中一个他从您创建的
列表中配对。它不会从字符串中删除任何内容。而且,您的第一个模式会找到任何“c”不管它是否在一个单词的开头。@ajb所有匹配项都保存到一个列表中。我正试图从第二个正则表达式列表中删除它们。Iterables来自Guava,我无法使用java 8函数。恐怕你只是增加了混淆。请看“我想要什么”,现在似乎您没有试图删除任何内容,但您希望对某些出现的“me”进行大写,而不是其他。我没有看到任何代码将任何内容大写,或将“me”替换为“me”。我想你需要提供一个。我试图澄清我的问题。你看,我想要的是在已经匹配的内容中不匹配任何内容,这是最有效的。不,这不起作用,因为我需要对正则表达式做两件独立的事情,并且用这件事我无法区分它们(可以吗?)不,除非使用组或其他正则表达式,否则不能使用。我在代码中使用的第一种方法是matcher.group()将给出正则表达式中哪个组进行了匹配。例如,如果匹配是以
c
开头的单词,它将返回1,因为组1进行了匹配。但事实并非如此。您知道获取此值的任何方法吗?@Croutonix我刚刚添加了一个示例,说明它如何使用第一种方法。因为我目前没有IDE不过,我只是在TutorialPoint上编译并运行了它。
for(String word: words) {                
    if(word.startsWith("c")) {
        // put in your list for words starting with "c"
    } else if (word.contains("me")) {
        // put in your list for words containing "me"
    }
}