2010-02-18 10 views
6

Estoy tratando de entender esta declaración RegEx en detalles. Se supone que valida el nombre de archivo del control ASP.Net FileUpload para permitir solo archivos jpeg y gif. Fue diseñado por otra persona y no lo entiendo completamente. Funciona bien en Internet Explorer 7.0 pero no en Firefox 3.6.Comprender esta declaración RegEx

<asp:RegularExpressionValidator id="FileUpLoadValidator" runat="server" 
    ErrorMessage="Upload Jpegs and Gifs only." 
    ValidationExpression="^(([a-zA-Z]:)|(\\{2}\w+)\$?)(\\(\w[\w].*))(.jpg|.JPG|.gif|.GIF)$" 
    ControlToValidate="LogoFileUpload"> 
</asp:RegularExpressionValidator> 
+0

No estoy seguro de por qué esto tiene un voto hacia abajo. –

+2

porque es pedirle a la gente que pesque para él, no enseñarle a pescar. 3 upvotes realmente? Publique un millón de preguntas sobre "qué significa esta expresión regular", supongo. –

+0

Estoy de acuerdo con Brian, esto es bastante ridículo. –

Respuesta

4

Esto es una mala expresión regular.

^(([a-zA-Z]:)|(\\{2}\w+)\$?)(\\(\w[\w].*))(.jpg|.JPG|.gif|.GIF)$ 

Hagámoslo parte por parte.

([a-zA-Z]:) 

Esto requiere la ruta del archivo comienza con un letraUnidad como C:, d:, etc.

(\\{2}\w+)\$?) 

\\{2} significa que la barra invertida repite dos veces (tenga en cuenta las necesidades \ ser escapado), seguido de algunos caracteres alfanuméricos (\w+), y luego tal vez un signo de dólar (\$?). Esta es la parte de host de la ruta UNC.

([a-zA-Z]:)|(\\{2}\w+)\$?) 

El | significa "o". Entonces, o bien comienza con una letra de unidad o una ruta UNC. Felicitaciones por expulsar a los usuarios que no son de Windows.

(\\(\w[\w].*)) 

Esto si la parte del directorio de la ruta, pero en realidad es de 2 caracteres alfanuméricos seguidos por nada, salvo nuevas líneas (.*), como \[email protected]#*(#$*).

La expresión regular correcta para esta parte debe ser (?:\\\w+)+

(.jpg|.JPG|.gif|.GIF)$ 

Esto significa que los 3 últimos caracteres de la ruta debe ser jpg, JPG, gif o GIF. Tenga en cuenta que . es no un punto, pero coincide con cualquier cosa excepto \n, por lo que un nombre de archivo como haha.abcgif o malicious.exe\0gif pasará.

La expresión regular correcta para esta parte debe ser \.(?:jpg|JPG|gif|GIF)$

Juntos,

^(([a-zA-Z]:)|(\\{2}\w+)\$?)(\\(\w[\w].*))(.jpg|.JPG|.gif|.GIF)$ 

coincidirá con

D:\foo.jpg 
\\remote$\dummy\..\C:\Windows\System32\Logo.gif 
C:\Windows\System32\cmd.exe;--gif 

y se producirá un error

/home/user/pictures/myself.jpg 
C:\a.jpg 
C:\d\e.jpg 

La expresión regular es correcta /\.(?:jpg|gif)$/i, y comprobar si el archivo subido es realmente una imagen en el lado del servidor.

+0

¡GUAU! Muchas gracias por los detalles. Esto es lo que estaba buscando. Resuelve mi problema Todavía curioso por qué el original no funciona en Firefox. Puede ser un tema para una pregunta separada, pero probablemente no muy relevante para el tema principal aquí. – myforums

+0

Lo siento. Acabo de descubrir que '' no funciona para 'C: \ doc \ My Pictures \ cat-fish.gif' – myforums

9

He aquí una breve explicación:

^    # match the beginning of the input 
(    # start capture group 1 
    (   # start capture group 2 
    [a-zA-Z] #  match any character from the set {'A'..'Z', 'a'..'z'} 
    :   #  match the character ':' 
)    # end capture group 2 
    |    # OR 
    (   # start capture group 3 
    \\{2}  #  match the character '\' and repeat it exactly 2 times 
    \w+   #  match a word character: [a-zA-Z_0-9] and repeat it one or more times 
)    # end capture group 3 
    \$?   # match the character '$' and match it once or none at all 
)    # end capture group 1 
(    # start capture group 4 
    \\   # match the character '\' 
    (   # start capture group 5 
    \w   #  match a word character: [a-zA-Z_0-9] 
    [\w]  #  match any character from the set {'0'..'9', 'A'..'Z', '_', 'a'..'z'} 
    .*   #  match any character except line breaks and repeat it zero or more times 
)    # end capture group 5 
)    # end capture group 4 
(    # start capture group 6 
    .    # match any character except line breaks 
    jpg   # match the characters 'jpg' 
    |    # OR 
    .    # match any character except line breaks 
    JPG   # match the characters 'JPG' 
    |    # OR 
    .    # match any character except line breaks 
    gif   # match the characters 'gif' 
    |    # OR 
    .    # match any character except line breaks 
    GIF   # match the characters 'GIF' 
)    # end capture group 6 
$    # match the end of the input 

EDITAR

Como parte de la solicitud de comentarios, se genera la anterior por una pequeña herramienta que escribí. Puede descargar está aquí: http://www.big-o.nl/apps/pcreparser/pcre/PCREParser.html (ADVERTENCIA: en gran medida en fase de desarrollo!)

EDITAR 2

que coincidirá con cadenas como éstas:

x:\abc\def\ghi.JPG 
c:\foo\bar.gif 
\\foo$\baz.jpg 

Esto es lo que los grupos 1, 4 y 6 coincide de forma individual:

group 1 | group 4  | group 6 
--------+--------------+-------- 
     |    | 
x:  | \abc\def\ghi | .JPG 
     |    | 
c:  | \foo\bar  | .gif 
     |    | 
\\foo$ | \baz   | .jpg 
     |    | 

Nota que también coincide con una cadena como c:\foo\[email protected] desde la alfombra DOT ches cualquier personaje (excepto saltos de línea). Y rechazará una cadena como c:\foo\bar.Gif (capital G en gif).

+0

¿Puedo preguntar por ignorancia qué herramienta usaste para esto? – Skilldrick

+0

Bart K. ¿Podría publicar una URL que permita realizar este tipo de análisis? – myforums

+0

+1 ¡detallado! También me gustaría saber si esto fue producido por una herramienta. – Pharabus

1

Se divide un nombre de archivo en el boletín de unidad de piezas, ruta, nombre de archivo y extensión.

Lo más probable es que IE use barras diagonales inversas, mientras que FireFox utiliza barras diagonales. Intenta reemplazar las \\ partes con [\\ /] para que la expresión acepte tanto barras inclinadas como barras diagonales inversas.

+0

No. El intercambio \\ con [\\\ /] no ayudó. Aún no funciona en Firefox. – myforums

0

De Expresso esto es lo que dice Expresso:

 
/// A description of the regular expression: 
/// 
/// Beginning of line or string 
/// [1]: A numbered capture group. [([a-zA-Z]:)|(\\{2}\w+)\$?] 
///  Select from 2 alternatives 
///   [2]: A numbered capture group. [[a-zA-Z]:] 
///    [a-zA-Z]: 
///     Any character in this class: [a-zA-Z] 
///     : 
///   (\\{2}\w+)\$? 
///    [3]: A numbered capture group. [\\{2}\w+] 
///     \\{2}\w+ 
///      Literal \, exactly 2 repetitions 
///      Alphanumeric, one or more repetitions 
///    Literal $, zero or one repetitions 
/// [4]: A numbered capture group. [\\(\w[\w].*)] 
///  \\(\w[\w].*) 
///   Literal \ 
///   [5]: A numbered capture group. [\w[\w].*] 
///    \w[\w].* 
///     Alphanumeric 
///     Any character in this class: [\w] 
///     Any character, any number of repetitions 
/// [6]: A numbered capture group. [.jpg|.JPG|.gif|.GIF] 
///  Select from 4 alternatives 
///   .jpg 
///    Any character 
///    jpg 
///   .JPG 
///    Any character 
///    JPG 
///   .gif 
///    Any character 
///    gif 
///   .GIF 
///    Any character 
///    GIF 
/// End of line or string 
/// 

Espero que esto ayude, Saludos, Tom.

0

Es posible que deba implementar la validación del lado del servidor. Mira este artículo.

Solving the Challenges of ASP.NET Validation

También, hay algunas buenas herramientas en línea para crear o interpretar las expresiones expresiones regulares. pero sospecho que el problema no está en la expresión.

Cuestiones relacionadas