Как сопоставить текст, часть которого уже сопоставлена предыдущей?

#regex

#регулярное выражение

Вопрос:

У меня есть строка типа aaa**b***c****ddd , и я хочу получить последовательность совпадающего текста шаблона [^*]* [^*] , за что я должен поблагодарить [a**b, b***c, c***d] . Однако, когда я тестирую это в текстовом редакторе, таком как vim или emacs, второй ( b***c ) не соответствует.

 aaa**b***c***ddd
  |--|   |---|
  first  third
     |---|
     second, which I think should be matched but not 
  

Как я должен изменить регулярное выражение, чтобы оно соответствовало второму?

Комментарии:

1. Насколько я знаю, регулярное выражение всегда «использует» каждый символ один раз. Таким образом, вероятно, нет решения для этого, кроме как дважды сопоставить строку…

Ответ №1:

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

 (?=([^*]* [^*]))
  

Но вы не можете использовать это для замены, поскольку этот шаблон ничему не соответствует. (или, возможно, если вы можете получить длину группы захвата и текущее смещение)

Редактировать:

кажется, можно получить длину группы захвата с помощью vim с strlen(submatch(1))

Комментарии:

1. 1 Я собирался опубликовать это, но не был уверен в языке, который он использовал.

2. Это то, чего я хотел. Спасибо.

Ответ №2:

@CommuSoft правильно. Одним из способов решения этой проблемы было бы сопоставить всю строку с этим регулярным выражением, а затем во второй раз сопоставить это регулярное выражение с подстрокой, которая начинается с (index_of_first_previous_match 1) до конца строки. Надеюсь, это понятно.

Итак, если индекс вашего первого совпадения выше (a ** b) был 2. Тогда новая подстрока, которую вы сопоставляете с регулярным выражением во второй раз, должна начинаться с индекса 3 до конца строки. Это даст вам два результата.

Однако ответ Казимира намного проще.