Как обрезать строку (содержащую путь), не касаясь имени файла?

Как обрезать строку (содержащую путь), не касаясь имени файла (сохранить последнюю папку, имя файла и букву диска)?

Привет, я ищу способ обрезать путь, чтобы он соответствовал указанной ширине.

Я уже искал SO и нашел это: Обрезать строку, чтобы она соответствовала заданной ширине в пикселях

Но это добавление... в конце строки. Я хотел бы иметь аналогичную функцию, но нужно сохранить начало и конец.

Например, у меня есть этот путь (строка):

H:\Informatique\Personnalisation\Icones\__\Crystal GT PNG Pack\Applications\licq.png

И он должен соответствовать ширине div следующим образом:

H:\Informatique\...PNG Pack\Applications\licq.png

Еще один пример:

D:\A___VERY___________LONG________PATH____________\myfile.png

Будет сокращено до:

D:\A___VERY___________LONG________PA...\myfile.png

Последний пример:

D:\A___VERY___________LONG________PATH____________\and-a-sub-solder\myfile.png

Будет сокращено до:

D:\A___VERY________...\and-a-sub-solder\myfile.png

Ограничение:

  • Требуется приводная часть (H:)
  • Требуется имя файла и расширение (licq.png)
  • Если есть несколько папок, последняя папка не должна быть усечена, за исключением случаев, когда все уже усечено, и это единственный способ сделать строку короче.
  • Если имя файла слишком длинное, обрежьте его посередине.

Пример длинного имени файла:

D:\my____file___________________________name____is___too____________long.png

Будет сокращено до:

D:\my____file_________..._is___too____________long.png

Я вижу, что Windows и Apple делают это хорошо... но я не могу найти ни одного сценария, близкого к этому.

Любая ссылка с подобным скриптом, чтобы я мог попробовать настроить его? Или кто-нибудь, кто хочет помочь мне с этим? :)

Большое спасибо


person Jeremy Dicaire    schedule 13.01.2013    source источник
comment
Есть ли более конкретные правила для усечения длинных имен файлов?   -  person gronostaj    schedule 14.01.2013
comment
Существует ли правило, когда многоточие идет в начале (пример 1), в конце (пример 2 и 3) или в середине (пример 4) усеченного имени каталога/файла?   -  person pawel    schedule 14.01.2013
comment
Это просто логика, если мы обрежем в конце, пользователь не увидит имя файла, в начале пользователь не увидит букву диска. Последняя папка вообще что-то говорит пользователю... Program File ничего не значит для большинства из них ;) - Если вы хотите больше примеров, просто спросите!   -  person Jeremy Dicaire    schedule 14.01.2013


Ответы (2)


Это интересная проблема, вот мое решение: http://jsfiddle.net/AlienHoboken/y7SgA/

Предполагается, что у вас есть переменная str с путем в ней и maxLength с максимальной длиной символа.

Вам нужно будет немного изменить код, так как str жестко закодирован, вам нужно будет изменить maxLength, и вам также нужно будет изменить, где вы записываете информацию (сейчас она просто пишет в тело).

NB: если имя вашего диска + имя файла превышают переменную maxLength, он просто распечатает эти два вместе, даже если они слишком велики.

Код, если вам не нравится jsfiddle:

$(document).ready(function () {
  var str = "H:\\Informatique\\Personnalisation\\Icones\\__\\Crystal GT PNG Pack\\Applications\\licq.png";
  var maxLength = 25;

  var tokens = str.split("\\");
  var drive = tokens[0];
  var fileName = tokens[tokens.length - 1];
  var len = drive.length + fileName.length;
  //remove the current lenth and also space for 3 dots and 2 slashes
  var remLen = maxLength - len - 5;

  //if remLen < 0, then it will over flow our maxLength to still maintain drive and     filename
  if (remLen > 0) {
    //remove first and last elements from the array
    tokens.splice(0, 1);
    tokens.splice(tokens.length - 1, 1);
    //recreate our path
    var path = tokens.join("\\");
    //handle the case of an odd length
    var lenA = Math.ceil(remLen / 2);
    var lenB = Math.floor(remLen / 2);
    //rebuild the path from beginning and end
    var pathA = path.substring(0, lenA);
    var pathB = path.substring(path.length - lenB);
    path = drive + "\\" + pathA + "..." + pathB + "\\" + fileName;

    //write it out
    $("body").html("Orig. Path: " + str + "<br /><br />" +
      "New Path: " + path + "<br /><br />" +
      "MaxLength: " + maxLength + "<br /><br />" +
      "New Length: " + path.length);
  } else {

    //try and fit our maxlength by taking only drive and filename
    $("body").html("Orig. Path: " + str + "<br /><br />" +
      "New Path: " + drive + "\\" + fileName + "<br /><br />" +
      "MaxLength: " + maxLength + "<br /><br />" +
      "New Length: " + (len + 1) + "<br /><br />");
  }
});
person AlienHoboken    schedule 13.01.2013
comment
Хороший! Удивительно! Я смогу работать с этим, чтобы завершить то, что я хочу выполнить. Спасибо AlienHoboken за этот ответ. Жесткий код не проблема;) - person Jeremy Dicaire; 14.01.2013
comment
Без проблем. Наслаждайся, приятель. знак равно - person AlienHoboken; 14.01.2013
comment
Очень хороший код, но если у вас есть путь к файлу, например H:\ploppy\licq.png, тогда ваш скрипт выдаст H:\plopp...loppy\licq.png, что, вероятно, не является желаемым результатом. Я думаю, нужно просто проверить, превышает ли длина строки максимальную длину, и вернуть строку нетронутой, если это не так. - person Jacques; 03.10.2018

Позвольте мне просто добавить немного оптимизированную версию кода @AlienHoboken. Эта версия

  • работает для путей с или без диска в начале строки
  • работает для путей с разделителем / или \
  • можно опустить имя файла, когда нам нужно показать только путь к папке

Надеюсь, поможет!

function pathShorten(str, maxLength, removeFilename) {
    var splitter = str.indexOf('/')>-1 ? '/' : "\\",
        tokens = str.split(splitter), 
        removeFilename = !!removeFilename,
        maxLength = maxLength || 25,
        drive = str.indexOf(':')>-1 ? tokens[0] : "",  
        fileName = tokens[tokens.length - 1],
        len = removeFilename ? drive.length  : drive.length + fileName.length,    
        remLen = maxLength - len - 5, // remove the current lenth and also space for 3 dots and 2 slashes
        path, lenA, lenB, pathA, pathB;    
    //remove first and last elements from the array
    tokens.splice(0, 1);
    tokens.splice(tokens.length - 1, 1);
    //recreate our path
    path = tokens.join(splitter);
    //handle the case of an odd length
    lenA = Math.ceil(remLen / 2);
    lenB = Math.floor(remLen / 2);
    //rebuild the path from beginning and end
    pathA = path.substring(0, lenA);
    pathB = path.substring(path.length - lenB);
    path = drive + splitter + pathA + "..." + pathB + splitter ;
    path = path + (removeFilename ? "" : fileName); 
    //console.log(tokens, maxLength, drive, fileName, len, remLen, pathA, pathB);
    return path;
}
person JohnPan    schedule 22.09.2017
comment
Вау, невероятно. Некоторые люди засмеялись, когда я спросил об этом, но то, что я объяснил выше, просто, это предотвращает путаницу — важная информация остается видимой. Завтра попробую ваш вариант, очень интересно протестировать. Спасибо! - person Jeremy Dicaire; 22.09.2017