Нежадное регулярное выражение в Java

У меня есть следующий код:

public static void createTokens(){
    String test = "test is a word word word word big small";
    Matcher mtch = Pattern.compile("test is a (\\s*.+?\\s*) word (\\s*.+?\\s*)").matcher(test);
    while (mtch.find()){
        for (int i = 1; i <= mtch.groupCount(); i++){
            System.out.println(mtch.group(i));
        }
    }
}

И иметь следующий вывод:

word
w

Но на мой взгляд должно быть:

word
word

Кто-нибудь, объясните мне, почему так?


person Divers    schedule 19.01.2012    source источник


Ответы (2)


Поскольку ваши шаблоны не являются жадными, поэтому они соответствуют как можно меньшему количеству текста, но при этом состоят из совпадений.

Удалить ? во второй группе, и вы получите
слово
слово слово большое маленькое

Matcher mtch = Pattern.compile("test is a (\\s*.+?\\s*) word (\\s*.+\\s*)").matcher(test);
person theglauber    schedule 19.01.2012
comment
И теперь вторая группа улавливает слишком много, а не слишком мало. Нежадность — не проблема, а жадность — не решение. - person Alan Moore; 19.01.2012
comment
Вы правы, но ИМХО нежадность второй группы захвата объясняет, почему она захватывает просто w. Первая группа захвата должна захватить слово из-за следующего за ним буквального слова. Я не знаю точно, что он ищет, и он отредактировал вопрос после того, как я отправил свой ответ, поэтому я не могу предоставить правильное регулярное выражение. - person theglauber; 19.01.2012

Используя \\s*, он будет соответствовать любому количеству пробелов, включая 0 пробелов. w соответствует (\\s*.+?\\s*). Чтобы убедиться, что оно соответствует слову, разделенному пробелами, попробуйте (\\s+.+?\\s+)

person Garrett Hall    schedule 19.01.2012
comment
Проблема в том, что регулярное выражение уже потребляет символы пробела до и после слова, поэтому теперь вы пытаетесь использовать их дважды. - person Alan Moore; 19.01.2012
comment
Все, что вам нужно сделать, это удалить пробел из регулярного выражения, например ...\\s+)word(\\s+... - person Daniel Gray; 05.07.2017