Ответ 1
Это правильное выражение:
string regex = @"^[\w\-. ]+$";
\w
эквивалентен [0-9a-zA-Z_]
.
Я уже рассмотрел какой-то вопрос в StackOverflow относительно этого, но в моем случае ничего не помогло.
Я хочу ограничить пользователя предоставлением имени файла, который должен содержать только буквенно-цифровые символы, -
, _
, .
и пробел.
Я не очень хорош в регулярных выражениях, и до сих пор я придумал этот ^[a-zA-Z0-9.-_]$
. Может кто-нибудь мне помочь?
Это правильное выражение:
string regex = @"^[\w\-. ]+$";
\w
эквивалентен [0-9a-zA-Z_]
.
Чтобы проверить имя файла, я бы предложил использовать функцию, предоставленную С#, а не регулярное выражение
if (filename.IndexOfAny(System.IO.Path.GetInvalidFileNameChars()) != -1)
{
}
Хотя то, что запрашивает ОП, близко к тому, что использует принятый в настоящее время ответ (^[\w\-. ]+$
), Могут быть и другие, видящие этот вопрос, у которых есть еще более конкретные ограничения.
Во-первых, при работе на компьютере, отличном от US/GB, \w
разрешит широкий спектр нежелательных символов из иностранных языков в соответствии с ограничениями OP.
Во-вторых, если расширение имени файла включено в имя, это позволяет использовать любые странные, но действительные имена файлов, такие как file.txt
или file...txt
.
В-третьих, если вы просто загружаете файлы в свою файловую систему, вам может понадобиться черный список файлов и/или расширений, подобных этим:
web.config, hosts,.gitignore, httpd.conf,.htaccess
Однако это значительно выходит за рамки этого вопроса; это потребовало бы всех видов информации о настройке для хорошего руководства по вопросам безопасности. Я думал, что должен поднять вопрос, тем не менее.
Так что для решения, где пользователь может ввести полное имя файла, я хотел бы пойти примерно так:
^[a-zA-Z0-9](?:[a-zA-Z0-9 ._-]*[a-zA-Z0-9])?\.[a-zA-Z0-9_-]+$
Это гарантирует, что используется только английский алфавит, без начальных и конечных пробелов, и гарантирует использование расширения файла с длиной не менее 1 и без пробелов.
Я протестировал это на Regex101, но для дальнейшего использования это был мой "набор тестов":
## THE BELOW SHOULD MATCH
web.config
httpd.conf
test.txt
1.1
my long file name.txt
## THE BELOW SHOULD NOT MATCH - THOUGH VALID
æøå.txt
hosts
.gitignore
.htaccess
В случае, если кому-то еще нужно проверить имена файлов (включая зарезервированные слова Windows и т.д.), Здесь полное выражение: \A(?!(?:COM[0-9]|CON|LPT[0-9]|NUL|PRN|AUX|com[0-9]|con|lpt[0-9]|nul|prn|aux)|[\s\.])[^\\\/:*"?<>|]{1,254}\z
? \A(?!(?:COM[0-9]|CON|LPT[0-9]|NUL|PRN|AUX|com[0-9]|con|lpt[0-9]|nul|prn|aux)|[\s\.])[^\\\/:*"?<>|]{1,254}\z
Изменение: для заинтересованного здесь ссылка на соглашения об именах файлов Windows: https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx
используйте это регулярное выражение ^[a-zA-Z0-9._ -]+$
Это незначительное изменение в ответах инженеров.
string regex = @"^[\w\- ]+[\w\-. ]*$"
Это заблокирует ".txt"
, что недопустимо.
Проблема в том, что он блокирует "..txt"
, который действителен
Я могу сказать что-то глупое здесь, но мне кажется, что эти ответы неверны. Во-первых, мы говорим о Linux или Windows здесь (или о другой ОС)?
Во-вторых, в Windows это (я считаю) совершенно законно включать "$" в имя файла, не говоря уже о Unicode вообще. Это, безусловно, кажется возможным.
Я попытался получить окончательный источник на этом... и попал на страницу имени файла Wikip: в частности раздел "Зарезервированные символы и слова", по-видимому, имеет значение: и это, безусловно, список вещей, которые вам НЕ разрешено Путин.
Я в мире Java. И я, естественно, предположил, что Apache Commons будет иметь что-то вроде validateFilename
, возможно, в FilenameUtils
... но он выглядит не так (если бы это было сделано, это все равно было бы потенциально полезным для программистов на С#, поскольку код обычно довольно легко понять и поэтому можно перевести). Я сделал эксперимент, хотя, используя метод normalize
: к моему разочарованию он позволил совершенно недопустимым символам (? И т.д.) "Пройти".
Часть страницы Wikip Filename, ссылка на которую приведена выше, показывает, что этот вопрос зависит от используемой ОС... но должно быть возможно собрать хотя бы простое регулярное выражение для Linux и Windows.
Затем я нашел способ Java (по крайней мере):
Path path = java.nio.file.FileSystems.getDefault().getPath( 'bobb??::mouse.blip' );
выход:
java.nio.file.InvalidPathException: Недопустимый символ в индексе 4: bobb?? :: mouse.blip
... предположительно разные объекты FileSystem
будут иметь разные правила проверки
Я только что создал это. Он предотвращает две точки и точку в конце и начале. Однако он не допускает никаких двух точек.
^([a-zA-Z0-9_]+)\.(?!\.)([a-zA-Z0-9]{1,5})(?<!\.)$
Для полного набора символов (Unicode) используйте
^[\p{L}0-9_\-.~]+$
или возможно
^[\p{L}\p{N}_\-.~]+$
будет более точным, если мы говорим о Unicode.
Я добавил '~' просто потому, что у меня есть несколько файлов, использующих этот символ.
Скопировано из @Engineer для дальнейшего использования, поскольку точка не была экранирована (как следует) в большинстве голосованных ответов.
Это правильное выражение:
string regex = @"^[\w\-\. ]+$";