理解这个RegEx声明

时间:2010-02-18 15:12:59

标签: c# asp.net regex file-upload validation

我试图详细了解这个RegEx声明。它应该从ASP.Net FileUpload控件验证文件名,只允许jpeg和gif文件。它是由其他人设计的,我不完全理解它。它在Internet Explorer 7.0中工作正常,但在Firefox 3.6中没有。

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

5 个答案:

答案 0 :(得分:9)

这是一个简短的解释:

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

修改

正如一些评论所要求的那样,上面是由我写的一个小工具生成的。你可以在这里下载:http://www.big-o.nl/apps/pcreparser/pcre/PCREParser.html(警告:正在开发中!)

编辑2

它会匹配这些字符串:

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

以下是第1组,第4组和第6组分别匹配的内容:

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

请注意,它也匹配c:\foo\bar@gif之类的字符串,因为DOT匹配任何字符(换行符除外)。并且它会拒绝c:\foo\bar.Gif中的字符串G中的大写gif

答案 1 :(得分:4)

这是一个糟糕的正则表达式。

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

让我们一个接一个地做。

([a-zA-Z]:)

这要求文件路径以C:d:等驱动器开头。

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

\\{2}表示重复两次反斜杠(注意\需要转义),然后是一些字母数字(\w+),然后可能是一个美元符号({{1} })。这是UNC路径的主持部分。

\$?

([a-zA-Z]:)|(\\{2}\w+)\$?) 表示“或”。因此要么以驱动器号或UNC路径开头。恭喜您推出非Windows用户。

|

此应的路径的目录的一部分,但实际上是2个字母数字,接着,除了新行任何东西((\\(\w[\w].*)) ),例如.*

此部分的正确正则表达式应为\ab!@#*(#$*)

(?:\\\w+)+

这意味着路径的最后3个字符必须是(.jpg|.JPG|.gif|.GIF)$ jpgJPGgif。注意,GIF的一个点,但匹配除了.,所以像一个文件名\nhaha.abcgif将通过任何东西。

此部分的正确正则表达式应为malicious.exe\0gif

总之,

\.(?:jpg|JPG|gif|GIF)$

将匹配

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

并将失败

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

正确的正则表达式是/home/user/pictures/myself.jpg C:\a.jpg C:\d\e.jpg ,并检查上传的文件是否真的是服务器端的图像

答案 2 :(得分:1)

它将文件名拆分为部分driveletter,路径,文件名和扩展名。

当FireFox使用斜杠时,IE很可能使用反斜杠。尝试用[\\ /]替换\\部分,以便表达式接受斜杠和反斜杠。

答案 3 :(得分:0)

来自Expresso这就是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
///  

希望这有帮助, 最好的祝福, 汤姆。

答案 4 :(得分:0)

您可能需要实施服务器端验证。看看这篇文章。

Solving the Challenges of ASP.NET Validation

此外,还有一些很好的在线工具可用于创建或解释Regex表达式。但我怀疑问题不在于表达方式。