Группы Захвата Регулярных Выражений Java



Я пытаюсь понять этот блок кода. В первом случае, что мы ищем в выражении?



Я понимаю, что это любой символ (0 или более раз*), за которым следует любое число от 0 до 9 (один или более раз+), за которым следует любой символ (0 или более раз *).



когда это выполняется, результат такой:



Found value: This order was placed for QT3000! OK?
Found value: This order was placed for QT300
Found value: 0


может кто-то пожалуйста, пройти через это со мной?



в чем преимущество использования захвата группы?



import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexTut3 {

public static void main(String args[]) {
String line = "This order was placed for QT3000! OK?";
String pattern = "(.*)(d+)(.*)";

// Create a Pattern object
Pattern r = Pattern.compile(pattern);

// Now create matcher object.
Matcher m = r.matcher(line);

if (m.find()) {
System.out.println("Found value: " + m.group(0));
System.out.println("Found value: " + m.group(1));
System.out.println("Found value: " + m.group(2));
} else {
System.out.println("NO MATCH");
}
}

}
584   4  

4 ответов:

проблема, с которой вы столкнулись, связана с типом квантора. Вы используете жадина Квантор в вашей первой группе (индекс 1 - индекс 0 представляет собой целую Pattern), что означает, что он будет соответствовать столько, сколько он может (и так как это любой характер, он будет соответствовать как много символов как есть для того, чтобы выполнить условие для следующей группы).

короче говоря, ваша 1-я группа .* все матчи пока следующей группа \d+ может соответствовать что-то (в данном случае, последняя цифра).

в 3-й группе, он будет соответствовать что-нибудь после последней цифры.

если вы измените его в хочет Квантор в вашей 1-й группе, вы получите результат, который я полагаю, вы ожидаете, то есть 3000 часть.

Примечание вопрос в 1-й группе.

String line = "This order was placed for QT3000! OK?";
Pattern pattern = Pattern.compile("(.*?)(\d+)(.*)");
Matcher matcher = pattern.matcher(line);
while (matcher.find()) {
    System.out.println("group 1: " + matcher.group(1));
    System.out.println("group 2: " + matcher.group(2));
    System.out.println("group 3: " + matcher.group(3));
}

выход:

group 1: This order was placed for QT
group 2: 3000
group 3: ! OK?

подробнее о Java Patternздесь.

наконец, группы захвата разделены круглыми скобками и обеспечивают очень полезный способ использования обратных ссылок (среди прочего), как только ваш Pattern соответствует входу.

в Java 6 групп, можно ссылаться только на их порядок (остерегайтесь вложенных групп и тонкость заказ).

в Java 7 это намного проще, так как вы можете использовать именованные группы.

это совершенно нормально.

  1. первая группа (m.group(0)) всегда захватывает вся область, которая покрыта вашим регулярным выражением. В данном случае это целая строка.
  2. регулярные выражения являются "жадными" по умолчанию, что означает, что первая группа захватывает как можно больше, не нарушая регулярное выражение. Элемент (.*)(\d+) (первая часть вашего регулярного выражения) охватывает ...QT300 int первая группа и 0 - во втором.
  3. вы можно быстро исправить это, сделав первую группу не жадной: change (.*) до (.*?).

для получения дополнительной информации о жадных и ленивых, проверить этого сайта.

ваше понимание правильно. Однако, если мы пройдем через:

  • (.*) проглотит всю строку;
  • он должен будет вернуть символы, так что (\d+) это satistifed (который является, почему 0 захвачен, а не 3000);
  • последние (.*) затем захватит остальные.

Я не уверен, что первоначальное намерение автора было, однако.

из документа :

Capturing groups</a> are indexed from left
 * to right, starting at one.  Group zero denotes the entire pattern, so
 * the expression m.group(0) is equivalent to m.group().

Так захватить группу 0 отправить всю строку.

Comments

    Ничего не найдено.