Слово для поведения, которое вы описали, не жадный , это притяжательное . Обычные, жадные квантификаторы совпадают настолько, насколько они могут изначально, но отступают, если необходимо, чтобы все регулярные выражения совпадали (мне нравится думать о них как о жадных, но вмещающих ). Вот что с вами происходит: %?
изначально соответствует лидирующему знаку процента, но если для общего совпадения осталось недостаточно символов, он отбрасывает знак процента и позволяет \S{3}
сопоставить его.
Некоторые разновидности регулярных выражений (включая Java и PHP) поддерживают собственнические квантификаторы , которые никогда не отступают, даже если это приводит к сбою общего соответствия. В .NET их нет, но есть следующая лучшая вещь: атомные группы . Все, что вы помещаете в атомарную группу, действует как отдельное регулярное выражение - оно либо совпадает с той позицией, в которой оно применено, либо нет, но оно никогда не возвращается назад и пытается сопоставить больше или меньше, чем изначально, просто потому, что остальные регулярное выражение терпит неудачу (то есть механизм регулярных выражений никогда не возвращает в атомную группу). Вот как бы вы использовали это для вашей проблемы:
^(?>%?)\S{3}
Если строка начинается со знака процента, ей соответствует (?>%?)
, и если для соответствия \S{3}
недостаточно символов, регулярное выражение завершается неудачей.
Обратите внимание, что атомные группы (или притяжательные кванторы) не нужны для решения этой проблемы, как продемонстрировал @Dav. Но это очень мощные инструменты, которые могут легко сделать разницу между невозможным и возможным , или слишком чертовски медленным и гладким, как может быть .