¿Por qué importa el orden de las alternativas en expresiones regulares?

Código

using System; using System.Text.RegularExpressions; namespace RegexNoMatch { class Program { static void Main () { string input = "a foobar& b"; string regex1 = "(foobar|foo)&?"; string regex2 = "(foo|foobar)&?"; string replace = "$1"; Console.WriteLine(Regex.Replace(input, regex1, replace)); Console.WriteLine(Regex.Replace(input, regex2, replace)); Console.ReadKey(); } } } 

Rendimiento esperado

 a foobar b a foobar b 

Salida real

 a foobar b a foobar& b 

Pregunta

¿Por qué la sustitución no funciona cuando se cambia el orden de “foo” y “foobar” en el patrón de expresiones regulares? ¿Cómo arreglar esto?

El motor de expresiones regulares intenta hacer coincidir las alternativas en el orden en que se especifican. Entonces, cuando el patrón es (foo|foobar)&? coincide con foo inmediatamente y continúa tratando de encontrar coincidencias. El siguiente bit de la cadena de entrada es bar& b que no se puede combinar.

En otras palabras, como foo es parte de foobar , no hay forma (foo|foobar) coincidir con foobar , ya que siempre coincidirá con foo primero.

Ocasionalmente, esto puede ser un truco muy útil, en realidad. El patrón (o|a|(\w)) le permitirá capturar \w y a o o diferente:

 Regex.Replace("a foobar& b", "(o|a|(\\w))", "$2") // fbr& b