PHP Regex как совместить до [duplicate]

Оператор == всегда предназначен для сравнения ссылок на объекты, тогда как метод сравнения строк .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)
352
задан smci 16 November 2017 в 01:27
поделиться

11 ответов

Жадный будет потреблять как можно больше. Из http://www.regular-expressions.info/repeat.html мы видим пример попытки сопоставить HTML-теги с <.+>. Предположим, что у вас есть следующее:

<em>Hello World</em>

Вы можете подумать, что <.+> (. означает любой символ новой строки и + означает один или несколько ) будет соответствовать только <em> и </em>, когда на самом деле это будет очень жадно и перейти от первого < к последнему >. Это означает, что он будет соответствовать <em>Hello World</em> вместо того, что вы хотели.

Сделать это ленивым (<.+?>) предотвратит это. Добавив ? после +, мы просим его повторить как можно меньше , поэтому первый >, с которым он сталкивается, - это то, где мы хотим остановить сопоставление.

Я бы посоветовал вам скачать RegExr , отличный инструмент, который поможет вам исследовать регулярные выражения - я использую его все время.

452
ответ дан Mibac 16 August 2018 в 02:10
поделиться
  • 1
    так что если вы используете жадные, у вас будет 3 (1 элемент + 2 тега) совпадения или всего одно совпадение (1 элемент)? – ajsie 20 February 2010 в 07:27
  • 2
    Он будет соответствовать только 1 раз, начиная с первого & lt; и заканчивая последним & gt; . – Sampson 20 February 2010 в 07:28
  • 3
    Но сделать это ленивым будет соответствовать дважды, давая нам как открывающий и закрывающий тег, игнорируя текст между ними (так как он не соответствует выражению). – Sampson 20 February 2010 в 07:29
  • 4
    regex101.com похож на jsfiddle для регулярного выражения. – nackjicholson 27 October 2014 в 06:18
  • 5
    Просто добавлю, что есть и жадный способ обойти это: <[^>]+> regex101.com/r/lW0cY6/1 – alanbuchanan 15 June 2015 в 12:57

Из Регулярное выражение

Стандартные кванторы в регулярных выражениях жадные, что означает, что они соответствуют столько, сколько они могут, только при необходимости возвращаясь, чтобы соответствовать остатку регулярного выражения.

Используя ленивый квантификатор, выражение сначала пытается выполнить минимальное совпадение.

5
ответ дан Adriaan Stander 16 August 2018 в 02:10
поделиться

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

abcdefghijklmc

и это выражение:

a.*c

Жадное соответствие будет соответствовать всей строке, а ленивое соответствие будет соответствовать только первому abc.

45
ответ дан Carl Norum 16 August 2018 в 02:10
поделиться

попытайтесь понять следующее поведение:

    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); // ""
-2
ответ дан FrankyHollywood 16 August 2018 в 02:10
поделиться

Насколько я знаю, большинство движков regex по умолчанию жадные. Добавить знак вопроса в конце квантификатора даст возможность ленивого совпадения.

Как указано в комментарии @Andre S.

  • Жадный: продолжайте поиск до тех пор, пока условие не будет выполнено.
  • Lazy: прекратить поиск, когда условие выполнено.

Обратитесь к приведенному ниже примеру для жадного и ленивого.

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 долларов

9
ответ дан Gearon 16 August 2018 в 02:10
поделиться

Лучше всего показано на примере. Строка. 192.168.1.1 и жадное регулярное выражение \ b. + \ B Возможно, вы думаете, что это даст вам 1-й октет, но на самом деле соответствует всей строке. ЗАЧЕМ!!! Поскольку. + Жадный и жадный матч соответствует каждому символу в '192.168.1.1', пока он не достигнет конца строки. Это важный бит !!! Теперь он начинает возвращать один символ за раз, пока не найдет совпадение для третьего токена (\ b).

Если строка с текстовым файлом 4 ГБ и 192.168.1.1 была в начале, вы могли легко увидеть как этот откат вызовет проблему.

Чтобы сделать регулярное выражение, не жадное (ленивое), поставить вопросительный знак после вашего жадного поиска, например *? ?? +? Теперь происходит токен 2 (+?) Находит совпадение, регулярное выражение перемещается вдоль символа, а затем пытается использовать следующий токен (\ b), а не токен 2 (+?). Таким образом, он медленно дергается.

2
ответ дан Jason Alcock 16 August 2018 в 02:10
поделиться
+-------------------+-----------------+------------------------------+
| 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  |
+-------------------+-----------------+------------------------------+

Добавить? к квантификатору, чтобы сделать его нелогичным, ленивым.

Пример: тестовая строка: stackoverflow greedy reg expression : s.*o output: stackoverflow ] lazy reg expression : s.*?o output: stackoverflow

65
ответ дан Premraj 16 August 2018 в 02:10
поделиться
  • 1
    не является ?? эквивалентно? , Точно так же не {an}? эквивалентно {n} – Breaking Benjamin 2 September 2016 в 08:07
  • 2
    @BreakingBenjamin: нет ?? не эквивалентен?, когда у него есть выбор, чтобы либо вернуть 0, либо 1 вхождение, он будет выбирать 0 (ленивую) альтернативу. Чтобы увидеть разницу, сравните 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

1
ответ дан Selva 16 August 2018 в 02:10
поделиться

«Greedy» означает совпадение длинной возможной строки.

«Lazy» означает совпадение кратчайшей строки.

Например, жадный h.+l соответствует 'hell' в 'hello', но ленивый h.+?l соответствует 'hel'.

219
ответ дан smci 16 August 2018 в 02:10
поделиться
  • 1
    Блестящий, так ленивый остановится, как только условие l будет удовлетворено, но жадный означает, что он остановится только после того, как условие l не будет удовлетворено больше? – Andrew S 23 February 2014 в 23:27
  • 2
    Для всех людей, читающих сообщение: жадные или ленивые кванторы сами по себе не будут соответствовать самой длинной / кратчайшей возможной подстроке. Вы должны использовать либо умеренный жадный токен , либо использовать подходы без регулярных выражений. – Wiktor Stribiżew 15 October 2016 в 21:29
  • 3
    @AndrewS Не путайте двойное ll в примере. Это довольно ленивый будет соответствовать кратчайшей подстроке, в то время как жадный будет соответствовать максимально возможному. Greedy h.+l соответствует 'helol' в 'helolo', но ленивый h.+?l соответствует 'hel'. – v.shashenko 21 March 2017 в 17:38
  • 4
    @FloatingRock: Нет. x? означает x необязательно, но +? является другим синтаксисом. Это означает, что вы остановите поиск после того, как найдете что-то, что соответствует - ленивое совпадение. – slebetman 14 April 2017 в 12:56
  • 5
    @FloatingRock: Что касается того, как вы различаете различный синтаксис, просто: ? означает необязательный параметр, а +? означает «ленивый». Поэтому \+? означает + необязательно. – slebetman 14 April 2017 в 12:57

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

Lazy остановится, как только он встретит первый шаблон, который вы запросили.

Одним из распространенных примеров, с которыми я часто сталкиваюсь, является \s*-\s*? регулярного выражения ([0-9]{2}\s*-\s*?[0-9]{7})

. Первый \s* классифицируется как жадный из-за * и будет выглядеть как можно больше белых пробелов после того, как встречаются цифры, а затем найдите тире «-». Где второй \s*? является ленивым из-за присутствия *?, что означает, что он будет выглядеть первым символом пробела и останавливаться прямо там.

1
ответ дан stackFan 16 August 2018 в 02:10
поделиться

Взято из www.regular-expressions.info

Жадность: жадные кванторы сначала пытаются повторить токен столько раз, насколько это возможно, и постепенно отбрасывают спички в качестве двигателя назад

Laziness: Lazy quantifier сначала повторяет токен столько раз, сколько требуется, и постепенно расширяет совпадение, когда двигатель возвращается в регулярное выражение, чтобы найти полное соответствие.

8
ответ дан Suganthan Madhavan Pillai 16 August 2018 в 02:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: