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

Я хочу разрешить любые символы от 0 до 2 между каждой группой в регулярном выражении (this is)?.??.??(an)?.??.??(example sentence). Он должен соответствовать выделенному полужирным шрифтом тексту в следующих строках:

бла бла. Пример предложения
бла-бла. Это пример предложения
Что-то что-то Пример предложения

Теперь в первом примере совпадение равно ah. example sentence. Я думал добавить 2 вопросительных знака к "." будет означать, что механизм регулярных выражений предпочтет соответствовать 0 символов.

Я использую регулярное выражение в VBA в MS Word, реализованное CreateObject("vbscript.regexp"), которое, как я понимаю, использует вариант регулярного выражения VBScript, который, как я понимаю, такой же, как вариант JavaScript.


person Some_Guy    schedule 17.01.2017    source источник
comment
@wiktor-stribiżew, почему это дубликат? Насколько я вижу, я намеренно использую не жадный, но получаю жадное совпадение. Это не рассматривается в связанном вопросе.   -  person Some_Guy    schedule 17.01.2017
comment
Вы, кажется, неправильно понимаете, как работают жадные и ленивые квантификаторы. Связанный поток имеет дело с этим. Квантификаторы не влияют на место, где найдено совпадение. Механизм регулярных выражений анализирует текст слева направо. Как только он сможет сопоставить часть текста с шаблоном, он это сделает.   -  person Wiktor Stribiżew    schedule 17.01.2017
comment
(это).*?(an).*?(пример предложения)   -  person Lonnie Best    schedule 17.01.2017
comment
@LonnieBest Спасибо, но я хочу сопоставить не более двух символов между каждым подвыражением и сопоставить, даже если подвыражение отсутствует.   -  person Some_Guy    schedule 17.01.2017
comment
Я думаю, вам нужно изменить вопрос, чтобы подчеркнуть реальную проблему. Мне кажется, вам просто нужно использовать .{0,2} (или даже .{1,2}) внутри необязательных групп, (this is.{0,2})?(an.{0,2})?(example sentence), см. это демо.   -  person Wiktor Stribiżew    schedule 17.01.2017
comment
@WiktorStribiżew Это решает проблему, спасибо. Почему размещение вне групп имеет значение? При поиске 0020002101 не следует ли 2.??.??.??101 предпочесть 2101 20002101?   -  person Some_Guy    schedule 17.01.2017
comment
Regex egine не может ничего предпочесть. Соответствует слева направо. Как только 2 найден (первый 2), он начинает сопоставляться с последующими подшаблонами, и когда совпадение найдено, оно возвращается.   -  person Wiktor Stribiżew    schedule 17.01.2017
comment
Я действительно думаю, что нежадный квантификатор регулярного выражения дает жадный результат лучше дурак на этот вопрос.   -  person Sebastian Proske    schedule 17.01.2017
comment
msdn.microsoft.com/en-us/library Кстати, я использовал ссылку /az24scfc(v=vs.110).aspx. Очень обманчиво: | ?? | Соответствует предыдущему элементу ноль или один раз, но как можно меньше раз. |   -  person Some_Guy    schedule 22.01.2017


Ответы (1)


При поиске 0020002101 не следует ли 2.??.??.??101 предпочесть 2101 20002101?

Regex egine не может ничего «предпочесть». Соответствует слева направо. Как только найден 2 (первый 2), он начинает сопоставляться с последующими подшаблонами, и когда совпадение найдено, он возвращается.

В вашем случае вам нужно использовать .{0,2} внутри необязательных групп,

(this is.{0,2})?(an.{0,2})?(example sentence)
        ^^^^^^     ^^^^^^

См. демонстрацию регулярного выражения.

Если важен порядок необязательных строк, сделайте их вложенными:

(this is.{0,2}(an.{0,2})?)?(example sentence)

См. другую демонстрацию регулярного выражения. Это регулярное выражение будет соответствовать только an с символами от 0 до 2 после него, только если перед ним будет найдено this is с символами от 0 до 2.

person Wiktor Stribiżew    schedule 17.01.2017
comment
Спасибо. Это многое проясняет. - person Some_Guy; 17.01.2017
comment
Я немного поэкспериментировал с этим и изменил исходное регулярное выражение на (this is)??.??.??(an)??.??.??(example sentence). Я ожидал, что будет сопоставлено только пример предложения, но... regex101. Первые две группы сопоставляются в любом случае. Есть идеи, почему? - person SamWhan; 17.01.2017
comment
Подсказка: переключитесь на разновидность регулярных выражений PCRE на regex101.com и нажмите отладчик регулярных выражений. Вы увидите внутренности сопоставления, которые довольно распространены в этих механизмах регулярных выражений NFA. Ожидаются ваши матчи. Если вам нужно вообще избежать возврата совпадения, вам придется использовать утверждения lookarounds/zero-width, которые ограничивают контекст совпадения и не возвращают совпадающие тексты со значением совпадения. - person Wiktor Stribiżew; 17.01.2017