在JavaScript中修剪文件名的最有效方法

wsxa1bj1  于 2023-02-02  发布在  Java
关注(0)|答案(5)|浏览(147)

我想知道如何修剪JS中的文件名,以便在一定数量的字符后显示“...”或任何附录,这是处理所有可能的测试用例的最有效方法。

规则

1.显示实际的文件扩展名,而不是用“”拆分字符串名称后的最后一个字符。
1.该函数应将输入文件名(字符串)、要修剪的字符数(整数)和附录(字符串)作为参数。
1.所谓高效,我的意思是我希望编写更少的代码行并处理所有可能的边缘情况。

输入示例

  1. myAwesomeFile.min.css
    1.我的超棒的File.tar.gz
  2. file.png

预期输出(假设我想在5个字符后进行修剪)

  1. myAwe....min.css
    1.我的奥...塔.格兹
  2. file.png

编辑问题以显示我的尝试

function trimFileName(str, noOfChars, appendix) {
  let nameArray = str.split(".");
  let fileType = `.${nameArray.pop()}`;
  let fileName = nameArray.join(" ");

  if (fileName.length >= noOfChars) {
    fileName = fileName.substr(0, noOfChars) + appendix;
  };

  return (fileName + fileType);
}

console.log(trimFileName("myAwesomeFile.min.css", 5, "..."));
console.log(trimFileName("my Awesome File.tar.gz", 5, "..."));
console.log(trimFileName("file.png", 5, "..."));

**编辑#2:**如果您认为这不是标准预期,请随意编辑问题,并向样本输入和预期输出添加更多边缘情况。
**编辑#3:**在新评论后添加了一些细节。我知道我的尝试没有达到我的预期输出(我不确定上面列出的输出是否是标准预期)。
**编辑#4(最终版):**删除了在评论中不断出现反对意见后不得在中间打断一个单词的规则,并更改了规则以满足更现实和实用的用例。

xxe27gdn

xxe27gdn1#

如果我们将点字符.作为文件扩展名的分隔符,那么您所要求的内容可以通过一行JavaScript来解决:

name.replace(new RegExp('(^[^\\.]{' + chars + '})[^\\.]+'), '$1' + subst);

以下代码段中的演示代码:

function f(name, chars, subst) {
  return name.replace(
    new RegExp('(^[^\\.]{' + chars + '})[^\\.]+'), '$1' + subst);
}


test('myAwesomeFile.min.css', 5, '...', 'myAwe....min.css');
test('my Awesome File.tar.gz', 5, '...', 'my Aw....tar.gz');
test('file.png', 5, '...', 'file.png');

function test(filename, length, subst, expected) {
  let actual = f(filename, length, subst);
  console.log(actual, actual === expected ? 'OK' : 'expected: ' + expected);
}

在Windows上,AFAIK的文件扩展名是最后一个点之后的扩展名,因此,从技术上讲,"myAwesomeFile.min.css"的文件扩展名是css"my Awesome File.tar.gz"的文件扩展名是gz
在这种情况下,您所请求的内容仍然可以通过一行JavaScript来解决:

name.replace(new RegExp('(^.{' + chars + '}).+(\\.[^\\.]*$)'), '$1' + subst + '$2');

以下代码段中的演示代码:

function f(name, chars, subst) {
  return name.replace(
    new RegExp('(^.{' + chars + '}).+(\\.[^\\.]*$)'), '$1' + subst + '$2');
}


test('myAwesomeFile.min.css', 5, '...', 'myAwe....css');
test('my Awesome File.tar.gz', 5, '...', 'my Aw....gz');
test('file.png', 5, '...', 'file.png');

function test(filename, length, subst, expected) {
  let actual = f(filename, length, subst);
  console.log(actual, actual === expected ? 'OK' : 'expected: ' + expected);
}

如果您真的希望允许具有特定多个扩展的边缘情况,您可能需要定义一个包含所有允许的多个扩展的完整列表,以了解如何处理"my.awesome.file.min.css"这样的情况。您需要提供一个包含所有要包含的情况的列表,然后才有可能确定任何解决方案的效率。

dauxcl2d

dauxcl2d2#

考虑所有的扩展(包括边缘情况)确实很难。常见扩展的例子见下表:https://www.computerhope.com/issues/ch001789.htm .事件具有这么多扩展名,因此该列表列出了所有扩展名。
你的函数是可以的,但是为了考虑更多的情况,它可以重写为:

function trimFileName(filename, limit = 5, spacer = '.') {
  const split = filename.indexOf(".");
  const name = filename.substring(0, split);
  const ext = filename.substring(split);

  let trimName = name.substring(0, limit);

  if (name.length > trimName.length)
    trimName = trimName.padEnd(limit + 3, spacer);

  return trimName + ext;
}

console.log(trimFileName("myAwesomeFile.min.css"));
console.log(trimFileName("my Awesome File.tar.gz"));
console.log(trimFileName("file.png"));
2eafrhcq

2eafrhcq3#

下面是一个非常简单的方法来实现你想要的方式缩短。注解是在代码中,但让我知道如果有什么需要额外的解释:

//A simple object to hold some configs about how we want to shorten the file names
const config = {
  charsBeforeTrim: 5,
  seperator: '.',
  replacementText: '....'
};

//Given file names to shorten
const files = ['myAwesomeFile.min.css', 'my Awesome File.tar.gz', 'file.png'];

//Function to do the actual file name shortening
const shorten = s =>
  s.length > config.charsBeforeTrim ? `${s.substring(0, config.charsBeforeTrim)}${config.replacementText}` : s;

//Function to generate a short file name with extension(s)
const generateShortName = (file, config) => {
  //ES6 Array destructuring makes it easy to get the file name in a unique variable while keeping the remaining elements (the extensions) in their own array:
  const [name, ...extensions] = file.split(config.seperator);

  //Simply append all remaining extension chunks to the shortName
  return extensions.reduce((accum, extension) => {
    accum += `${config.seperator}${extension}`;
    return accum;
  }, shorten(name));
};

//Demonstrate usage
const shortFileNames = files.map(file => generateShortName(file, config));

console.log(shortFileNames);
g52tjvyc

g52tjvyc4#

const parse = (filename, extIdx = filename.lastIndexOf('.')) => ({
  name: filename.substring(0, extIdx),
  extension: filename.substring(extIdx + 1),
})

const trimFileName = (
  filename, size = 5, fill = '...', 
  file = parse(filename),
  head = file.name.substring(0, size)
) => file.name.length >= size ? `${head}${fill}${file.extension}` : filename

/* - - - - - - - - - - - - - - - - - - - - - - - - - */

;[
  'myAwesomeFile.min.css', 
  'my.Awesome.File.min.css',
  'my Awesome File.tar.gz',
  'file.png',
].forEach(f => console.log(trimFileName(f)))
omjgkv6w

omjgkv6w5#

你可以很直接地提取你的扩展名条件(很容易被一个有效扩展名的列表替换),然后正则表达式提取最后一部分,然后你只需要在文件名上添加一个检查(从文件名的开头开始)来修剪结果。

const trim = (string, x) => {
      // We assume that up to last two . delimited substrings of length are the extension
      const extensionRegex = /(?:(\.[a-zA-Z0-9]+){0,2})$/g;
      const { index } = extensionRegex.exec(string);
      // No point in trimming since result string would be longer than input
      if (index + 2 < x) {
        return string;
      }
      return string.substr(0, x) + ".." + string.substr(index);
    };

  /* Assert that we keep the extension */
  console.log("cat.tar.gz", trim("cat.tar.gz", 100) == "cat.tar.gz");
  console.log("cat.zip", trim("cat.zip", 100) == "cat.zip");
  /* Assert that we keep x characters before trim */
  console.log("1234567890cat.tar.gz",!trim("1234567890cat.tar.gz",10).includes("cat"));
  console.log("1234567890cat.zip", !trim("1234567890cat.zip", 10).includes("cat"));

相关问题