Xác thực các loại tệp bằng biểu thức chính quy


79

Tôi có biểu mẫu web .NET có điều khiển tải lên tệp được liên kết với trình xác thực biểu thức chính quy. Trình xác thực này cần xác thực rằng chỉ một số loại tệp nhất định mới được phép tải lên (jpg, gif, doc, pdf)

Biểu thức chính quy hiện tại thực hiện điều này là:


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

Tuy nhiên điều này dường như không hiệu quả ... bất cứ ai có thể cho tôi một chút reg ex giúp đỡ?


18
Tôi chắc rằng bạn biết điều này, nhưng, trong trường hợp sau đó ai đó tìm thấy câu hỏi này thì người đó không biết: Phương pháp này sẽ chỉ xác minh phần mở rộng của tệp, không phải loại thực tế của nó. Khi bạn nhận được tệp, bạn phải kiểm tra nội dung của nó để xác định nó thực sự là gì. Nếu bạn chỉ dựa vào tên, đó là một lỗ hổng bảo mật lớn.
Dave Sherohman 20/08/08

Câu trả lời:


169

Theo tôi, regex của bạn có vẻ hơi quá phức tạp. Ngoài ra, hãy nhớ rằng dấu chấm là một ký tự đặc biệt có nghĩa là "bất kỳ ký tự nào". Regex sau sẽ hoạt động (lưu ý các dấu chấm thoát):

^.*\.(jpg|JPG|gif|GIF|doc|DOC|pdf|PDF)$

Bạn có thể sử dụng một công cụ như Expresso để kiểm tra biểu thức chính quy của mình.


Khi thực hiện các biểu thức chính quy trong .NET, không bắt buộc phải liệt kê các khác biệt về cách viết hoa. Ví dụ, nó không chỉ có thể làm giảm khả năng đọc mà còn có thể làm giảm hiệu suất nếu nó được gọi trong một vòng lặp.
Joseph Ferris

2
Vấn đề là regex được sử dụng trong một điều khiển RegularExpressionValidator ASP.NET, AFAIK không chấp nhận các tùy chọn như Bỏ quaCase.
Dario Solera

Tôi đã bỏ lỡ điều đó trong bài viết gốc. Đúng vậy, các tùy chọn phân biệt chữ hoa chữ thường RegularExpressionValidator là thứ mà Microsoft đã phớt lờ những lời kêu gọi từ cộng đồng trong một vài năm nay.
Joseph Ferris

1
Bạn có thể bỏ dấu ^. * Là "khớp với bất kỳ thứ gì từ đầu cho đến khi biểu thức này ở cuối" giống như "khớp biểu thức này ở cuối". Bạn cũng có thể nhúng các tùy chọn biểu thức chính quy msdn.microsoft.com/en-us/library/yd1hzczs.aspx
ICR

Để nhúng tùy chọn biểu thức chính quy để bỏ qua trường hợp, bạn cần phải tắt tập lệnh ClientSide (tôi không nghĩ JavaScript hỗ trợ nó). Sau đó, bạn có thể sử dụng use "(? I:. (Jpg | gif | doc | pdf)) $" cho một đối sánh không phân biệt chữ hoa chữ thường.
Martin Brown

19
^.+\.(?:(?:[dD][oO][cC][xX]?)|(?:[pP][dD][fF]))$

Sẽ chấp nhận các tệp .doc, .docx, .pdf có tên tệp gồm ít nhất một ký tự:

^           = beginning of string
.+          = at least one character (any character)
\.          = dot ('.')
(?:pattern) = match the pattern without storing the match)
[dD]        = any character in the set ('d' or 'D')
[xX]?       = any character in the set or none 
              ('x' may be missing so 'doc' or 'docx' are both accepted)
|           = either the previous or the next pattern
$           = end of matched string

Cảnh báo! Nếu không bao gồm toàn bộ chuỗi các phần mở rộng trong (? :), một phần mở rộng như .docpdf sẽ vượt qua.

Bạn có thể kiểm tra các cụm từ thông dụng tại http://www.regextester.com/


16

Bạn chỉ muốn xác minh rằng tệp có phải là một phần mở rộng nhất định không? Bạn có thể đơn giản hóa những gì bạn đang cố gắng thực hiện với những thứ như sau:

(.*?)\.(jpg|gif|doc|pdf)$

Sau đó, khi bạn gọi IsMatch (), hãy đảm bảo truyền RegexOptions.IgnoreCase làm tham số thứ hai của bạn. Không có lý do gì để phải liệt kê ra các biến thể cho cách viết hoa.

Chỉnh sửa: Như Dario đã đề cập, điều này sẽ không hoạt động với RegularExpressionValidator, vì nó không hỗ trợ các tùy chọn viết hoa.


1
Cái này cho phép dấu chấm để được đưa vào tên file đó là tốt cho tôi
Bronek

12

Bạn có thể nhúng phân biệt chữ hoa chữ thường vào biểu thức chính quy như sau:

\.(?i:)(?:jpg|gif|doc|pdf)$

1
Ngoại trừ trường hợp này không thành công nếu bạn bật tùy chọn tập lệnh ứng dụng khách.
Martin Brown

Afaik javascript không cho phép các tùy chọn nội tuyến, nhưng nó áp dụng cho toàn bộ regex chứ không chỉ mọi thứ sau nó, điều này không quan trọng trong trường hợp này. Trừ khi có lý do khác, nó sẽ không hoạt động (tôi không thể kiểm tra atm).
ICR

2
Không, JS hoàn toàn không hỗ trợ các công cụ sửa đổi nội tuyến. Ngoài ra, regex của bạn sẽ không hoạt động ngay cả trong .NET; bạn muốn "\. (? i) (?: jpg | gif | doc | pdf) $" hoặc "\. (? i: jpg | gif | doc | pdf) $". Điều này: "(? I :)" không khớp với nhau, không phân biệt chữ hoa chữ thường.
Alan Moore

6

Bạn có thể sử dụng mẫu này cho mọi loại tệp:

ValidationExpression="^.+\.(([pP][dD][fF])|([jJ][pP][gG])|([pP][nN][gG])))$"

ví dụ: bạn có thể thêm ( [rR][aA][rR]) cho loại tệp Rar và v.v.


5

Regexp của bạn dường như xác thực cả tên tệp và phần mở rộng. Có phải đó là những gì bạn cần? Tôi sẽ cho rằng đó chỉ là phần mở rộng và sẽ sử dụng regexp như thế này:

\.(jpg|gif|doc|pdf)$

Và đặt đối sánh không phân biệt chữ hoa chữ thường.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.