Regex ведет себя лениво, должен быть жадным

Я думал, что по умолчанию у моего Regex появится жадное поведение, которое я хочу, но оно не находится в следующем коде:

 Regex keywords = new Regex(@"in|int|into|internal|interface");
 var targets = keywords.ToString().Split('|');
 foreach (string t in targets)
    {
    Match match = keywords.Match(t);
    Console.WriteLine("Matched {0,-9} with {1}", t, match.Value);
    }

Вывод:

Matched in        with in
Matched int       with in
Matched into      with in
Matched internal  with in
Matched interface with in

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

  • Я хочу понять, почему это работает не так, как ожидалось, и
  • фактический проект, над которым я работаю имеет много слов в Regex и важно сохранить их в в алфавитном порядке.

Итак, мой вопрос: почему это лениво и как его исправить?

Ответ 1

Лень и жадность применяются только к квантизаторам (?, *, +, {min,max}). Чередования всегда совпадают по порядку и пробуют первое возможное совпадение.

Ответ 2

Похоже, вы пытаетесь сломать вещи. Для этого вам нужно, чтобы все выражение было правильным, ваше текущее - нет. Попробуйте это вместо этого.

new Regex(@"\b(in|int|into|internal|interface)\b");

"\ b" говорит, что соответствует границам слов и соответствует нулевой ширине. Это поведение зависит от локали, но в целом это означает пробелы и пунктуации. Будучи совпадением с нулевой шириной, он не будет содержать символ, который заставил механизм регулярных выражений обнаружить границу слова.

Ответ 3

Согласно RegularExpressions.info, регулярные выражения eager. Поэтому, когда он проходит через ваше piped expression, он останавливается на первом сплошном совпадении.

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