Чем заменить слэш в имени файла

Slash и backslash: вехи на пути

Немного истории

Slash
Backslash

Боб Бемер ввел обратный слеш (\) в набор символов ASCII, 18 сентября 1961 года, как результат изучения частоты использования символов встречающихся в частности в программах на ALGOL’е. Тогда же вместе с обратным слешем в стандарт были включены и квадратные скобки.
В частности \ был введен, чтобы булевы операторы ALGOL’a AND и OR могли быть представлены с помощью ASCII символов как «/\» и «\/» соответственно [3,4].
Как же вышло, что исторически православный слеш заменился на свое зеркальное отображение, введенное как вспомогательный символ специально для уже мертвого языка?

Русскоязычная Википедия по этому говорит вот что:
В операционных системах DOS и Windows фирмы Microsoft и их аналогах других разработчиков, обратная косая используется для разделений имён директорий (каталогов) при указании пути к файлу. Прямая косая, применяемая для этого в Unix не могла быть использована в MS-DOS, потому что уже была задействована для указания ключей командной строки (оставшегося в наследство от СР/M, где MS-DOS команда «dir /w» писалась как «dir/w») [5].

Так как такое объяснение меня не слишком удовлетворило, пришлось найти статью «Why is the DOS path character «\»?» [6], которая вполне утолила моё любопытство. Вольный перевод избранных частей в моем исполнении:
То что символ «/» конфликтовал с разделителем пути другой относительно популярной ОС не был связан напрямую с разработчиками – в конце концов, DOS не поддерживал директорий, просто файлы в одном корневом каталоге.
Для MS-DOS 2.0 (в котором появился поддержка каталогов), дизайнеры DOSа выбрали гибридную версию – у них уже были имена дисков в наследство от DOS 1.0, поэтому разработчикам пришлось их использовать. И в дополнение к именам дисков они решили использовать *nix-style метод определения иерархии каталогов — вместо использования каталога в имени файла (как это было сделано в VMS и DEC-20), они просто сделали каталог и имя файла неотъемлемыми частями пути. Но с этим была проблема. Невозможно было использовать разделитель пути *nix (/), по той причине что слэш уже использовался как разделитель ключей.
Что им было делать? Они конечно могли использовать «.» как в DEC, но точка уже использовалась как разделитель между именем файла и расширением. Поэтому они выбрали наилучший вариант из оставшихся — символ «\», который был визуально похож на «/».Таким вот образом и был выбран символ «\» для разделения путей в DOS.
Кстати есть небольшой секрет про MS-DOS. Разработчики DOS не были довольны таким положением дел – они использовали Xenix [7] для почты и прочих вещей, поэтому они были знакомы со структурой *nix команд. Поэтому они добавили в ОС возможность принимать в качестве разделителя путей как «/» так и «\» (это работает и сегодня, кстати – попробуйте выполнить «notepad c:/boot.ini» под XP (если ваш пользователь имеет права админа)). Дальше — больше. Они добавили недокументированный системный вызов, чтобы изменить символ разделителя ключей. И обновили утилиты, чтобы те поддерживали этот флаг. Они даже добавили в config.sys параметр, SWITCHAR, который позволит пользователю установить разделитель ключей на «-«. Таким образом можно было превратить MS-DOS в *nix-style ОС, используя «-switch», и пути с разделителем «/».

Собственно к чему это все?

Меня побудила разобраться в этой теме следующая ситуация.
Была поставлена задача — наладить систему отчетов для автоматизированных тестов. Тесты у нас используются двух видов – Selenium (функциональные) и Jmeter (нагрузочные). Собственно в этом не было ничего сложного — для этих целей существует вполне себе open-source проект под названием logging selenium [8] и plugin для maven — chronos [9]. Настроив всё и протестировав отчеты локально, принялся за интеграцию с нашей CI — TeamCity. Вот тут-то меня и ждала та самая неожиданность, которая стала поводом для написания этой статьи.
После выполнения всех тестов отчет о Selenium-тестах имел следующий вид:

Чем заменить слэш в имени файла. Смотреть фото Чем заменить слэш в имени файла. Смотреть картинку Чем заменить слэш в имени файла. Картинка про Чем заменить слэш в имени файла. Фото Чем заменить слэш в имени файла

Всё отлично отображалось, и никаких отличий от локальной версии не было.
Но вот отчет, который отобразился для Jmeter-тестов, воодушевления не вызывал:

Чем заменить слэш в имени файла. Смотреть фото Чем заменить слэш в имени файла. Смотреть картинку Чем заменить слэш в имени файла. Картинка про Чем заменить слэш в имени файла. Фото Чем заменить слэш в имени файла
Напрочь отсутствовали все изображения на странице.
После просмотра исходного кода страницы стало понятно, что во всем виноват backslash. Ссылки на изображения были указаны в таком формате:

Справедливости ради стоит заметить, что изображения отсутствовали в Firefox, но прекрасно отображались в IE. Хотя если бы IE не отображал ресурсы в URI которых встречается обратный слеш, как разделитель пути для Windows, то в, и не без того подпорченной, репутации индийских программистов образовалась бы еще одна брешь.

Источник

Regex для замены символов, которые Windows не принимает в имени файла

Я пытаюсь создать регулярное выражение, которое обнаружит любой символ, который Windows не принимает как часть имени файла (это то же самое для других ОС? Честно говоря, не знаю).

в любом случае, это то, что у меня есть: [/:*?»<>|]

тестер на http://gskinner.com/RegExr/ показывает, что это работает. Для строки Allo*ha на * символ загорается, сигнализируя, что он найден. Должен ли я войти Allo**ha однако, только первый * загорается. Поэтому я думаю, что мне нужно изменить это регулярное выражение, чтобы найти все появления упомянутых персонажей, но я не уверен.

видите ли, на Java мне повезло, что у меня есть функция строку.replaceAll (регулярное выражение строки, замена строки). В описании говорится:

заменяет каждую подстроку этой строки, которая соответствует заданному регулярному выражению с учетом замена.

другими словами, даже если регулярное выражение найдет только первое, а затем прекратит поиск, эта функция все равно найдет их все.

однако я не чувствую, что могу рисковать. Кто-нибудь знает, как я могу это продлить?

11 ответов

правила имени файла Windows являются хитрый. Ты только царапаешь поверхность.

например, вот некоторые вещи, которые не являются допустимыми именами файлов, в дополнение к перечисленным вами chracters:

удаление специальных символов в одном подзаголовке regex, например String.replaceAll () недостаточно; вы можете легко получить что-то недопустимое, например пустую строку или трейлинг».’ или ‘ ’. Замена чего-то вроде «[^A-Za-z0-9_.]*» с ‘_’ Было бы лучше первый шаг. Но вам все равно понадобится обработка более высокого уровня на любой платформе, которую вы используете.

поскольку ответа не было достаточно, я сделал это сам. надеюсь, это поможет;)

для записи POSIX-совместимые системы (включая UNIX и Linux) поддерживают все символы, кроме нулевого символа ( ‘ ‘ ) и Слэш ( ‘/’ ) в именах файлов. Специальные символы, такие как пробел и звездочка, должны быть экранированы в командной строке, чтобы они не выполняли свои обычные роли.

Я использую чистое и простое регулярное выражение. Я даю символы, которые могут произойти, и через отрицание «^» я изменяю все другое как знак такого. «_»

например: Если вы не хотите быть в выражения «.»затем удалите»\\.»

String fileName = someString.replaceAll («[^a-zA-Z0-9\\-]», «_»);

Java имеет функцию replaceAll, но каждый язык программирования имеет способ сделать что-то подобное. Perl, например, использует g переключатель для обозначения глобальной замены. В Python

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

думаю, я кому-то помог.

вы можете попробовать разрешить только то, что вы хотите, чтобы пользователь мог ввести, например A-Z, a-z и 0-9.

кстати, набор запрещенных символов отличается в других ОС.

Я сделал один очень простой способ это работает для меня наиболее распространенных случаях:

%22 кодируется, если у вас есть qoute («) в именах файлов.

требуемое регулярное выражение / синтаксис (JS):

если последний бит является необязательным, используйте только тогда, когда вы хотите ограничить длину до 240.

другие полезные функции (JS-файлы):

Windows также не принимает » % » в качестве имени файла.

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

например, в Linux (многие дистрибутивы я знаю), некоторые пользователи могут иметь проблемы с файлами, содержащими [b]&! ] [ /- () [/b]. Символы разрешены в именах файлов, но они должны быть специально обработаны пользователи и некоторые программы имеют ошибки, вызванные их существованием.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *