Оператор == всегда предназначен для сравнения ссылок на объекты, тогда как метод сравнения строк .equals () переопределяется для сравнения содержимого:
String s1 = new String("abc");
String s2 = new String("abc");
System.out.println(s1 == s2); // It prints false (reference comparison)
System.out.println(s1.equals(s2)); // It prints true (content comparison)
Жадный будет потреблять как можно больше. Из http://www.regular-expressions.info/repeat.html мы видим пример попытки сопоставить HTML-теги с <.+>
. Предположим, что у вас есть следующее:
<em>Hello World</em>
Вы можете подумать, что <.+>
(.
означает любой символ новой строки и +
означает один или несколько ) будет соответствовать только <em>
и </em>
, когда на самом деле это будет очень жадно и перейти от первого <
к последнему >
. Это означает, что он будет соответствовать <em>Hello World</em>
вместо того, что вы хотели.
Сделать это ленивым (<.+?>
) предотвратит это. Добавив ?
после +
, мы просим его повторить как можно меньше , поэтому первый >
, с которым он сталкивается, - это то, где мы хотим остановить сопоставление.
Я бы посоветовал вам скачать RegExr , отличный инструмент, который поможет вам исследовать регулярные выражения - я использую его все время.
Стандартные кванторы в регулярных выражениях жадные, что означает, что они соответствуют столько, сколько они могут, только при необходимости возвращаясь, чтобы соответствовать остатку регулярного выражения.
Используя ленивый квантификатор, выражение сначала пытается выполнить минимальное совпадение.
blockquote>
Жадный означает, что ваше выражение будет соответствовать как можно большей группе, ленивое означает, что оно будет соответствовать самой маленькой группе. Для этой строки:
abcdefghijklmc
и это выражение:
a.*c
Жадное соответствие будет соответствовать всей строке, а ленивое соответствие будет соответствовать только первому abc
.
попытайтесь понять следующее поведение:
var input = "0014.2";
Regex r1 = new Regex("\\d+.{0,1}\\d+");
Regex r2 = new Regex("\\d*.{0,1}\\d*");
Console.WriteLine(r1.Match(input).Value); // "0014.2"
Console.WriteLine(r2.Match(input).Value); // "0014.2"
input = " 0014.2";
Console.WriteLine(r1.Match(input).Value); // "0014.2"
Console.WriteLine(r2.Match(input).Value); // " 0014"
input = " 0014.2";
Console.WriteLine(r1.Match(input).Value); // "0014.2"
Console.WriteLine(r2.Match(input).Value); // ""
Насколько я знаю, большинство движков regex по умолчанию жадные. Добавить знак вопроса в конце квантификатора даст возможность ленивого совпадения.
Как указано в комментарии @Andre S.
Обратитесь к приведенному ниже примеру для жадного и ленивого.
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Test {
public static void main(String args[]){
String money = "100000000999";
String greedyRegex = "100(0*)";
Pattern pattern = Pattern.compile(greedyRegex);
Matcher matcher = pattern.matcher(money);
while(matcher.find()){
System.out.println("I'm greeedy and I want " + matcher.group() + " dollars. This is the most I can get.");
}
String lazyRegex = "100(0*?)";
pattern = Pattern.compile(lazyRegex);
matcher = pattern.matcher(money);
while(matcher.find()){
System.out.println("I'm too lazy to get so much money, only " + matcher.group() + " dollars is enough for me");
}
}
}
Результат:
Я - greeedy, и я хочу 100000000 долларов. Это самое лучшее, что я могу получить.
Мне слишком ленив, чтобы заработать столько денег, мне достаточно всего 100 долларов
Лучше всего показано на примере. Строка. 192.168.1.1 и жадное регулярное выражение \ b. + \ B Возможно, вы думаете, что это даст вам 1-й октет, но на самом деле соответствует всей строке. ЗАЧЕМ!!! Поскольку. + Жадный и жадный матч соответствует каждому символу в '192.168.1.1', пока он не достигнет конца строки. Это важный бит !!! Теперь он начинает возвращать один символ за раз, пока не найдет совпадение для третьего токена (\ b).
Если строка с текстовым файлом 4 ГБ и 192.168.1.1 была в начале, вы могли легко увидеть как этот откат вызовет проблему.
Чтобы сделать регулярное выражение, не жадное (ленивое), поставить вопросительный знак после вашего жадного поиска, например *? ?? +? Теперь происходит токен 2 (+?) Находит совпадение, регулярное выражение перемещается вдоль символа, а затем пытается использовать следующий токен (\ b), а не токен 2 (+?). Таким образом, он медленно дергается.
+-------------------+-----------------+------------------------------+
| Greedy quantifier | Lazy quantifier | Description |
+-------------------+-----------------+------------------------------+
| * | *? | Star Quantifier: 0 or more |
| + | +? | Plus Quantifier: 1 or more |
| ? | ?? | Optional Quantifier: 0 or 1 |
| {n} | {n}? | Quantifier: exactly n |
| {n,} | {n,}? | Quantifier: n or more |
| {n,m} | {n,m}? | Quantifier: between n and m |
+-------------------+-----------------+------------------------------+
Добавить? к квантификатору, чтобы сделать его нелогичным, ленивым.
blockquote>Пример: тестовая строка: stackoverflow greedy reg expression :
s.*o
output: stackoverflow ] lazy reg expression :s.*?o
output: stackoverflow
re.match('(f)?(.*)', 'food').groups()
с re.match('(f)??(.*)', 'food').groups()
. В последнем случае (f)??
не будет соответствовать ведущему «f», даже если это возможно. Следовательно, «f» будет соответствовать второй группе захвата «. *». Я уверен, что вы можете построить пример с помощью '{n}?' слишком. По общему признанию, эти два очень редко используются.
– smci
16 November 2017 в 01:42
Жадное соответствие. Поведение регулярных выражений по умолчанию должно быть жадным. Это означает, что он пытается извлечь как можно больше до тех пор, пока он не будет соответствовать шаблону, даже если меньшая часть была бы синтаксически достаточной.
Пример:
import re
text = "<body>Regex Greedy Matching Example </body>"
re.findall('<.*>', text)
#> ['<body>Regex Greedy Matching Example </body>']
Вместо сопоставления до первое вхождение «>», оно извлекло всю строку. Это по умолчанию жадное или «воспринимать все» поведение регулярного выражения.
С другой стороны, ленивое сопоставление «берет как можно меньше». Это можно сделать, добавив ?
в конец шаблона.
Пример:
re.findall('<.*?>', text)
#> ['<body>', '</body>']
Если вы хотите получить только первое совпадение, используйте поиск вместо этого.
re.search('<.*?>', text).group()
#> '<body>'
Источник: Примеры Regex для Python
«Greedy» означает совпадение длинной возможной строки.
«Lazy» означает совпадение кратчайшей строки.
Например, жадный h.+l
соответствует 'hell'
в 'hello'
, но ленивый h.+?l
соответствует 'hel'
.
h.+l
соответствует 'helol'
в 'helolo'
, но ленивый h.+?l
соответствует 'hel'
.
– v.shashenko
21 March 2017 в 17:38
x?
означает x
необязательно, но +?
является другим синтаксисом. Это означает, что вы остановите поиск после того, как найдете что-то, что соответствует - ленивое совпадение.
– slebetman
14 April 2017 в 12:56
?
означает необязательный параметр, а +?
означает «ленивый». Поэтому \+?
означает +
необязательно.
– slebetman
14 April 2017 в 12:57
Жадный означает, что он будет потреблять ваш шаблон до тех пор, пока не останется ни одного из них, и он не сможет смотреть дальше.
Lazy остановится, как только он встретит первый шаблон, который вы запросили.
Одним из распространенных примеров, с которыми я часто сталкиваюсь, является \s*-\s*?
регулярного выражения ([0-9]{2}\s*-\s*?[0-9]{7})
. Первый \s*
классифицируется как жадный из-за *
и будет выглядеть как можно больше белых пробелов после того, как встречаются цифры, а затем найдите тире «-». Где второй \s*?
является ленивым из-за присутствия *?
, что означает, что он будет выглядеть первым символом пробела и останавливаться прямо там.
Взято из www.regular-expressions.info
Жадность: жадные кванторы сначала пытаются повторить токен столько раз, насколько это возможно, и постепенно отбрасывают спички в качестве двигателя назад
Laziness: Lazy quantifier сначала повторяет токен столько раз, сколько требуется, и постепенно расширяет совпадение, когда двигатель возвращается в регулярное выражение, чтобы найти полное соответствие.
<[^>]+>
regex101.com/r/lW0cY6/1 – alanbuchanan 15 June 2015 в 12:57