Aqui veremos as expressões regex Look Ahead e Look Behind.

Vamos imaginar o seguinte problema, temos uma string com zeros e ums (exemplo: "010001"), e devemos capturar todos os intervalos de zero que estão entre os numeros ums, exemplo: para a String "0100010010", devemos capturar ["000" , "00"], mas não queremos capturar os números "1". Para isso vamos usar as expressões de Look Behind e Look Ahead, essas expressões não incluem o valor no group.

      
import java.util.*;
import java.util.regex.*;

public class RegexLookAhead {

    public static void main (String ... args){
        List<String> names = Arrays.asList("0100010010");
        names.stream().forEach(RegexLookAhead::printGroups);
    }

    static void printGroups(String s){
        System.out.print(s + " groups: ");
        Matcher matcher = Pattern.compile("(?<=1)(0+)(?=1)").matcher(s);
        while(matcher.find()) System.out.print(matcher.group() + "," );
        System.out.print("\n");
    }

}

Vamos entender a regex "(?<=1)(0+)(?=1)". Primeiro a expressão (?<=), essa expressão chamasse Look Behind Positive, basicamente ela verifica se um valor precede, no nosso caso verificamos se o valor "1" precede o "0". Em seguida temos a expressão (0+), aqui estamos agrupando os valores "0" com o operador greedy (+). Por fim temos a expressão (?=), ela chamasse Look Ahead Positive, ela tem a mesma função da anterior, mas nesse caso checa se sucede, ou seja, se a direita do valor 0 possui o valor 1. Temos também as negações dessas expressões, como pode ser visto na tabela a seguir.

Nome Expressão Descrição
Look Behind Positive (?<=) Verifica se o valor após "=" precede
Look Ahead Positive (?=) Verifica se o valor após "=" sucede
Look Behind Negative (?<!) Verifica se o valor após "!" não precede
Look Ahead Negative (?!) Verifica se o valor após "!" não sucede