2010-08-13 9 views
6

Quiero validar un código fuente de C# para un motor de secuencias de comandos. Quiero asegurarme de que solo se haga referencia a los miembros de la clase System.Math. Intento crear una expresión regular que coincida con un punto, seguido de una letra mayúscula, seguida de cualquier número de caracteres de palabra, que termina en una palabra delimitada que NO está precedida por System.Math.Dolor de cabeza Regex

empecé con esto:

(?<!Math)\.[A-Z]+[\w]* 

que funciona bien para:

return Math.Max(466.89/83.449 * 5.5); // won’t flag this 
return Xath.Max(466.89/83.449 * 5.5); // will flag this 

que coincida correctamente .MAX cuando no está precedida de Matemáticas. Sin embargo, ahora que intento expandir la expresión regular para incluir System, no puedo hacer que funcione.

que he probado estas permutaciones de la expresión regular y más:

((?<!System\.Math)\.[A-Z]+[\w]*) 
((?<!(?<!System)\.Math)\.[A-Z]+[\w]*) 
((?<!System)\.(?<!Math)\.[A-Z]+[\w]*) 
((?<!System)|(?<!Math)\.[A-Z]+[\w]*) 
((?<!System\.Math)|(?<!Math)\.[A-Z]+[\w]*) 

El uso de estas declaraciones:

return System.Math.Max(466.89/83.449 * 5.5); 
return System.Xath.Max(466.89/83.449 * 5.5); 
return Xystem.Math.Max(466.89/83.449 * 5.5); 

He intentado todo lo que podía pensar, pero tampoco SIEMPRE coincide con el segundo elemento (.Math o .Xath anterior) o NO coincide con NADA.

Si alguien tuviera piedad de mí y señalara lo que estoy haciendo mal, lo apreciaría en gran medida.

Gracias de antemano, Welton

+0

Pensé que tenía una solución, pero ahora he redescubierto todas las expresiones enumeradas y también he destruido mi cerebro. ¡Muy complicado! –

+0

Will 'Math. Alguna vez aparecerá solo, o siempre estará precedido por' System'? –

+4

¿Ha considerado usar un compilador (CSharpCodeProvider) y luego usar el gráfico de objetos CodeDom para buscar referencias a cosas que no sean System.Math? Esto sería a prueba de balas, más legible y más flexible. –

Respuesta

2

El truco está en asegurarse de que nunca comiences a hacer coincidir un nombre de miembro en cualquier lugar, pero al principio. Luego, es una simple cuestión de utilizar un análisis anticipado para averiguar si lo que está mirando comienza con System.Math.. Prueba esta expresión regular:

(?<![\w.])(?!(?:System\.)?Math\.)(?:[A-Z]\w*\.)+[A-Z]\w*\b 

La búsqueda hacia atrás asegura que el partido no se inicia en el medio de una palabra (\w) o el medio de un nombre de miembro cualificado (.). Ahora, si falla la búsqueda anticipada, no puede saltar al principio del siguiente componente (por ejemplo, Math. en System.Math.) y volver a intentarlo. Es todo o nada.

Sin embargo, este partido se Math.Max si no es precedida por System.. ¿Realmente lo necesitas, o fue solo un paso intermedio en el desarrollo de una expresión regular para el nombre completo?

EDITAR: Seguí adelante e hice la parte System. opcional.

+0

¡Eso también funciona! – dawg

2

Si estás en busca de lo que se indica en el ejemplo, esta expresión regular lo harán.

^[\w\s]*?[A-Z]\w+\.[A-Z]\w+\.(?<!System\.Math\.)

que coincide con todas las llamadas a otra cosa que System.Math.XXX siempre y cuando: a) hay dos . en la convocatoria, b) que es llamada en una línea.

return System.Math.Max(466.89/83.449 * 5.5); // no match 
return System.Xath.Max(466.89/83.449 * 5.5); // match 
return Xystem.Math.Max(466.89/83.449 * 5.5); // match 
System.Math.Max(466.89/83.449 * 5.5); // no match 
System.Xath.Max(466.89/83.449 * 5.5); // match 
Xystem.Math.Max(466.89/83.449 * 5.5); // match 
return System.Math.Max(466.89/83.449 * 5.5); // no match 
return System.Xath.Max(466.89/83.449 * 5.5); // match 
return Xystem.Math.Max(466.89/83.449 * 5.5); // match 
Math.Max(466.89/83.449 * 5.5);    // no match - only one '.' 
System.Max.Math(466.89/83.449 * 5.5);  // match 

Estoy de acuerdo con los comentarios; Cualquier expresión regular es bastante frágil y solo debe considerarse una ayuda de tipo editor de texto. Necesitas un analizador si deseas que sea a prueba de balas.

+0

No funciona en el retorno Xath.Max ​​(466.89/83.449 * 5.5); –

+0

@Richard: ¿Afirmó el OP que deseaba coincidir con eso finalmente? Mi entendimiento era que 'Math.Max ​​(466.89/83.449 * 5.5);' y 'Xath.Max ​​(466.89/83.449 * 5.5);' donde desarrollos intermedios de su expresión regular ... – dawg

+0

No estoy seguro ... si él dice Está bien, entonces obtienes un punto. –

Cuestiones relacionadas