2010-02-18 19 views
6

Sto cercando di comprendere questa dichiarazione RegEx in dettaglio. Dovrebbe convalidare il nome del file dal controllo FileUpload di ASP.Net per consentire solo i file jpeg e gif. È stato progettato da qualcun altro e non lo capisco completamente. Funziona bene con Internet Explorer 7.0 ma non con Firefox 3.6.Informazioni sulla dichiarazione 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

Non so perché questo ha un voto negativo. –

+2

perché chiede alle persone di pescarlo, non insegnargli a pescare. 3 upvotes davvero? Posta una milion "cosa significa questo regex" domande credo. –

+0

Sono d'accordo con Brian, questo è abbastanza ridicolo. –

risposta

4

Questa è un'espressione regolare negativa.

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

Facciamolo parte per parte.

([a-zA-Z]:) 

Ciò richiede il percorso del file inizia con una lettera di unità come C:, d:, etc.

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

\\{2} significa che la barra rovesciata ripetuto due volte (notare le \ necessario fare l'escape), seguito da alcuni caratteri alfanumerici (\w+), e poi forse un segno del dollaro (\$?). Questa è la parte host del percorso UNC.

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

Il | significa "o". Quindi inizia con una lettera di unità o un percorso UNC. Congratulazioni per aver buttato fuori utenti non Windows.

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

Questa dovrebbe la parte di directory del percorso, ma in realtà è 2 caratteri alfanumerici seguiti da nulla, se non nuove linee (.*), come \[email protected]#*(#$*).

La regex corretta per questa parte dovrebbe essere (?:\\\w+)+

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

Ciò significa gli ultimi 3 caratteri del percorso devono essere jpg, JPG, gif o GIF. Si noti che . è non un punto, ma corrisponde a qualsiasi cifra eccetto lo \n, quindi verrà passato un nome file come haha.abcgif o malicious.exe\0gif.

L'espressione regolare appropriata per questa parte dovrebbe essere \.(?:jpg|JPG|gif|GIF)$

Insieme,

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

corrisponderà

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

e non riuscirà

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

L'espressione regolare corretta è /\.(?:jpg|gif)$/i, e verificare se il file caricato è in realtà un'immagine sul lato server.

+0

WOW! Grazie mille per i dettagli. Questo è quello che stavo cercando. Risolve il mio problema. Ancora curioso perché l'originale non funziona in Firefox. Può essere un argomento per una domanda separata, ma probabilmente non molto rilevante per l'argomento principale qui. – myforums

+0

Siamo spiacenti. Ho appena scoperto che "" non funziona con "C: \ doc \ My Pictures \ cat-fish.gif" – myforums

9

Ecco una breve spiegazione:

^    # 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 

EDIT

Come alcuni di richiesta commenti, quanto sopra è generato da un piccolo strumento che ho scritto. È possibile scaricare è qui: http://www.big-o.nl/apps/pcreparser/pcre/PCREParser.html (ATTENZIONE: pesantemente in fase di sviluppo!)

EDIT 2

abbinerà stringhe come questi:

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

Ecco quello che i gruppi 1, 4 e 6 corrispondono singolarmente:

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

Nota che corrisponda anche una stringa come c:\foo\[email protected] poiché il tappetino DOT ches qualsiasi carattere (tranne le interruzioni di riga). E rifiuterà una stringa come c:\foo\bar.Gif (capitale G in gif).

+0

Posso ignoratamente chiedere quale strumento hai usato per questo? – Skilldrick

+0

Bart K. Potresti pubblicare l'URL che consente di eseguire questo tipo di analisi? – myforums

+0

+1 dettagliato! Anch'io vorrei sapere se questo è stato prodotto da uno strumento. – Pharabus

1

Divide un nome file nelle parti driveletter, percorso, nome file ed estensione.

Molto probabilmente IE utilizza i backslash mentre FireFox utilizza le barre. Prova a sostituire le \\ parti con [\\ /] in modo che l'espressione accetti sia barre che barre rovesciate.

+0

No. Scambiare \\ con [\\\ /] non ha aiutato. Ancora non funziona in Firefox. – myforums

0

Da Expresso questo è ciò che Expresso dice:

 
/// 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 
/// 

Spero che questo aiuti, i migliori saluti, Tom.

0

Potrebbe essere necessario implementare la convalida sul lato server. Dai un'occhiata a questo articolo.

Solving the Challenges of ASP.NET Validation

Inoltre, ci sono alcuni buoni strumenti online per la creazione o l'interpretazione di espressioni regex. ma sospetto che il problema non riguardi l'espressione.

Problemi correlati