Мне нужно разобрать базовое имя в ruby из пути к файлу, который я получаю в качестве входных данных. Формат Unix отлично работает в Linux.
File.basename("/tmp/text.txt")
вернуть "text.txt".
Однако, когда я получаю ввод в формате Windows:
File.basename("C:\Users\john\note.txt")
или
File.basename("C:\\Users\\john\\note.txt")
«C:Usersjohn\note.txt» — это вывод (обратите внимание, что \n — это новая строка), но я не получил «note.txt».
Есть ли хорошее решение в ruby/rails?
Решение:
"C:\\test\\note.txt".split(/\\|//).last
=> "note.txt"
"/tmp/test/note.txt".split(/\\|//).last
=> "note.txt"
Если имя файла Linux не содержит \, оно будет работать.
@CarySwoveland Дополнительное примечание «\ note» рассматривается как символ новой строки (\n) ote.txt.

Попробуйте pathname:
require 'pathname'
Pathname.new('C:\Users\john\note.txt').basename
# => #<Pathname:note.txt>
Ссылка Как получить имя файла без расширения из пути к файлу в Ruby
@CarySwoveland, что ты имеешь в виду?
В OP использовались двойные кавычки без обратной косой черты.
Кажется, это не работает в Linux с использованием 2.6.1 Pathname.new('C:\Users\john\note.txt').basename #=> #<Pathname:C:\Users\john\note.txt>
@engineersmnky Это не будет работать в Linux, потому что Linux не обрабатывает обратную косую черту так же, как Windows.
@tadman моя точка зрения заключалась в том, что маловероятно, что сервер rails работает через IIS, поэтому это может быть нежизнеспособным вариантом.
Спасибо, но это не работает так, как File.basename в Linux ruby.
Обратная косая черта, в то время как Windows выражает вещи, просто гигантская неприятность. В строке с двойными кавычками они имеют особое значение, поэтому вам нужно сделать следующее:
File.basename("C:\\Users\\john\\note.txt")
Или используйте одинарные кавычки, чтобы избежать проблемы:
File.basename('C:\Users\john\note.txt')
Или используйте обычные косые черты, которые не затронуты:
File.basename("C:/Users/john/note.txt")
Где Ruby выполняет сопоставление для вас с разделителем пути для конкретной платформы.
Первые два у меня не работали на macos. Полагаю, из-за File::SEPARATOR. Итак, если не считать запуска этого кода в Windows. вызывающая сторона должна преобразовать косые черты в качестве шага предварительной обработки. :пожимаю плечами:
Кажется, что единственный способ - заменить `и` на /, а затем проанализировать его как путь к файлу Unix. Или испортите File::ALT_SEPARATOR. В любом случае, это изменит имена файлов Unix, такие как /tmp/test\file.txt :(
Я не уверен, что у вас проблемы с кодом. Я думаю, у вас проблемы с тестом.
Ruby также использует символ обратной косой черты для escape-последовательности в строках, поэтому, когда вы вводите строковый литерал "C:\Users\john\note.txt", Ruby рассматривает первые два символа обратной косой черты как недопустимые escape-последовательности и поэтому игнорирует escape-символ. \n относится к новой строке. Итак, для Ruby этот литерал такой же, как "C:Usersjohn\note.txt". В этой последовательности нет разделителей файлов, поскольку \n — это новая строка, а не обратная косая черта, за которой следует буква н, поэтому File.basename просто возвращает ее по мере ее получения.
Если вы запрашиваете пользовательский ввод либо в графическом пользовательском интерфейсе (GUI), либо в интерфейсе командной строки (CLI), пользователю, вводящему ввод, не нужно беспокоиться об управляющих последовательностях Ruby String; они имеют значение только для строковых литералов непосредственно в коде. Попытайся! Введите gets в IRB или Прай, введите или скопируйте путь к файлу, нажмите Enter и посмотрите, как Ruby отображает его как строковый литерал.
В Windows Ruby принимает пути, указанные с использованием как «/» (File::SEPARATOR), так и «\\» (Файл::ALT_SEPARATOR), поэтому вам не нужно беспокоиться о преобразовании, если вы не показываете его пользователю.
Вы правы с gets -> "C:\\Users\\john\\note.txt\n". Однако в Linux Ruby/Rails ни File, ни Pathname не могут его разобрать.
@malmed: я сейчас не в Windows, поэтому не могу проверить, но я уверен, что и файл, и путь должны нормально обрабатывать «C:\\Users\\john\\note.txt». Я подозреваю, что проблема заключается в конце новой строки (\n). Используйте String#chop.
Я тоже не на винде (но оба формата пути получаю). Я не сомневаюсь, что "C:\\Users\\john\\note.txt" нормально разбирается в Windows.
@malmed Вы хотите, чтобы пользователь ввел путь к файлу в веб-приложение, а затем ваше приложение манипулировало этим путем? Мне трудно представить себе вариант использования для этого. Очевидно, вы можете просто использовать String#split.
Примечание:
"C:\U".chars #=> ["C", ":", "U"].