В этом ниже регулярном выражении:

1.*(aaa|ccc)

Тестовая строка

1aaaccc

Есть только один матч с группой 1 ccc. Но должно быть два совпадения ааа и ссс

1
coolcool1994 14 Ноя 2019 в 22:02
1
(|) — это чередование, поэтому вы соответствуете либо aaa, либо ccc. Поскольку вы указали 1.*(aaa|ccc), оно будет соответствовать 1aaaccc, захватывая ccc, поскольку регулярное выражение хочет соответствовать как можно большему числу. Точно так же изменение его на 1.*?(aaa|ccc) (ленивое сопоставление) будет соответствовать только 1aaa. Я думаю, что вы ищете, возможно, 1.*(a{3})(c{3})
 – 
ctwheels
14 Ноя 2019 в 22:35
Можете ли вы добавить больше примеров, чтобы лучше прояснить ваши требования.
 – 
anubhava
14 Ноя 2019 в 22:50
Вы можете сделать это правильно с чистым регулярным выражением только в Perl6. Вы можете использовать обходные пути для этого текущего сценария только в большинстве разновидностей регулярных выражений (см. Верхний комментарий) или решениях, основанных на некотором коде и регулярном выражении. Каков ваш вкус регулярного выражения?
 – 
Wiktor Stribiżew
14 Ноя 2019 в 23:35

1 ответ

Зависит от того, что вы ищете; Шаблон "1.*(aaa|ccc)" извлечет две группы:

  1. «1aaaccc»: «1» + любые символы + «ccc». 'ccc' выбрано как 'жадное' соответствие по умолчанию: извлечь как можно больше.

  2. "ccc" - потому что "ccc" находится в "группе захвата". Вы можете подавить это, изменив шаблон на "1.*(?:aaa|ccc)". Это «ccc», а не «aaa», потому что оно представляет собой часть уже существующего совпадения. Все необязательные совпадения после первого являются фрагментами первого.

Если убрать ".*", то "ccc" станет неактуальным и будут "1aaa" и "aaa". Если вы хотите получить как "aaa", так и "ccc", шаблон должен быть "1(aaa)(ccc)". Результат будет: "1aaaccc", "aaa", "ccc". Но это может быть не то, что вам нужно: строка «1xxxccc» не будет соответствовать ничему.

Это для регулярного выражения .NET, другие варианты, скорее всего, дадут тот же результат. Надеюсь, мое описание имеет смысл :)

1
Andrei Kalantarian 14 Ноя 2019 в 22:49
the first one — это полное совпадение, формально это не группа захвата. На самом деле известен как the match.
 – 
user12097764
15 Ноя 2019 в 01:17