Поймите это заявление RegEx - PullRequest
6 голосов
/ 18 февраля 2010

Я пытаюсь понять это утверждение 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 ]

9 голосов
/ 18 февраля 2010

Вот краткое объяснение:

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

Как некоторые из запросов на комментарии, вышеприведенное генерируется небольшим инструментом, который я написал. Вы можете скачать здесь: 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, поскольку точка соответствует любому символу (кроме разрывов строк). И он отклонит строку типа c:\foo\bar.Gif (заглавная G в gif).

4 голосов
/ 18 февраля 2010

Это плохое регулярное выражение.

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

Давайте сделаем это по частям.

([a-zA-Z]:)

Для этого требуется, чтобы путь к файлу начинался с буквы диска, например C:, d: и т. Д.

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

\\{2} означает, что обратная косая черта повторяется дважды (обратите внимание, что \ необходимо экранировать), затем идут буквенно-цифровые цифры (\w+), а затем, возможно, знак доллара (\$?). Это основная часть пути UNC.

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

| означает «или». Так что либо начинается с буквы диска или пути UNC. Поздравляем с выгонкой не-Windows пользователей.

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

Это должна быть часть пути каталога, но на самом деле это 2 алфавитно-цифровых символа, за которыми следует что угодно, кроме новых строк (.*), например, \ab!@#*(#$*).

Правильное регулярное выражение для этой части должно быть (?:\\\w+)+

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

Это означает, что последние 3 символа пути должны быть jpg, JPG, gif или GIF. Обратите внимание, что . - это , а не точка, но соответствует всему, кроме \n, поэтому имя файла, например haha.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

Правильное регулярное выражение /\.(?:jpg|gif)$/i и проверьте, действительно ли загруженный файл является изображением на стороне сервера .

1 голос
/ 18 февраля 2010

Он разбивает имя файла на букву диска частей, путь, имя файла и расширение.

Скорее всего, IE использует обратную косую черту, а FireFox использует косую черту. Попробуйте заменить \\ части на [\\ /], чтобы выражение принимало как косые, так и обратные косые черты.

0 голосов
/ 18 февраля 2010

Возможно, вам потребуется реализовать проверку на стороне сервера. Проверьте эту статью.

Решение проблем проверки ASP.NET

Кроме того, есть несколько хороших онлайн-инструментов для создания или интерпретации выражений Regex. но я подозреваю, что проблема не в выражении.

0 голосов
/ 18 февраля 2010

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

Надеюсь, это поможет, С наилучшими пожеланиями, Том.

...