Вопреки дезинформации, приведенной выше, регулярные выражения чрезвычайно эффективны. Предостережение заключается в том, что, когда это возможно, они должны находиться в таком положении, чтобы они компилировались ровно один раз за время существования программы.
Вот решение, которое дает dirname и basename .
const rx1 = /(.*)\/+([^/]*)$/; // (dir/) (optional_file)
const rx2 = /()(.*)$/; // () (file)
function dir_and_file(path) {
// result is array with
// [0] original string
// [1] dirname
// [2] filename
return rx1.exec(path) || rx2.exec(path);
}
// Single purpose versions.
function dirname(path) {
return (rx1.exec(path) || rx2.exec(path))[1];
}
function basename(path) {
return (rx1.exec(path) || rx2.exec(path))[2];
}
Что касается производительности, я не измерял ее, но я ожидаю, что это решение будет в том же диапазоне, что и самое быстрое из других на этой странице, но это решение делает больше. В реальной производительности помогает тот факт, что rx1
будет соответствовать большинству реальных путей, поэтому rx2
выполняется редко.
Вот тестовый код.
function show_dir(parts) {
console.log("Original str :"+parts[0]);
console.log("Directory nm :"+parts[1]);
console.log("File nm :"+parts[2]);
console.log();
}
show_dir(dir_and_file('/absolute_dir/file.txt'));
show_dir(dir_and_file('relative_dir////file.txt'));
show_dir(dir_and_file('dir_no_file/'));
show_dir(dir_and_file('just_one_word'));
show_dir(dir_and_file('')); // empty string
show_dir(dir_and_file(null));
А вот что дает тестовый код:
# Original str :/absolute_dir/file.txt
# Directory nm :/absolute_dir
# File nm :file.txt
#
# Original str :relative_dir////file.txt
# Directory nm :relative_dir
# File nm :file.txt
#
# Original str :dir_no_file/
# Directory nm :dir_no_file
# File nm :
#
# Original str :just_one_word
# Directory nm :
# File nm :just_one_word
#
# Original str :
# Directory nm :
# File nm :
#
# Original str :null
# Directory nm :
# File nm :null
Кстати, «узел» имеет встроенный модуль с именем «путь», который имеет «dirname» и «basename». Функция Node «path.dirname ()» точно имитирует поведение «dirname» оболочки «bash», но хорошо ли это? Вот что он делает:
- Создает
'.'
(точка), когда path==""
(пустая строка).
- Производит
'.'
(точка) при path=="just_one_word"
.
- Производит
'.'
(точка), когда path=="dir_no_file/"
.
Я предпочитаю результаты функции, определенной выше.