Skip to content

Commit 2c255c8

Browse files
committed
Генерация нового имени при копировании.
1 parent 545b1f3 commit 2c255c8

File tree

5 files changed

+218
-0
lines changed

5 files changed

+218
-0
lines changed

Diff for: README.md

+1
Original file line numberDiff line numberDiff line change
@@ -221,3 +221,4 @@
221221
# Регулярные выражения
222222

223223
- [Замена всех встреч слова в строке](regex/regex-repl-word)
224+
- [Генерация нового имени при копировании](regex/inc-filename)

Diff for: regex/inc-filename/.gitignore

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# ---------------------------------------------------------------------------
2+
# https://github.com/github/gitignore/blob/master/C++.gitignore
3+
4+
# Prerequisites
5+
*.d
6+
7+
# Compiled Object files
8+
*.slo
9+
*.lo
10+
*.o
11+
*.obj
12+
13+
# Precompiled Headers
14+
*.gch
15+
*.pch
16+
17+
# Compiled Dynamic libraries
18+
*.so
19+
*.dylib
20+
*.dll
21+
22+
# Fortran module files
23+
*.mod
24+
*.smod
25+
26+
# Compiled Static libraries
27+
*.lai
28+
*.la
29+
*.a
30+
*.lib
31+
32+
# Executables
33+
*.exe
34+
*.out
35+
*.app
36+
37+
# ---------------------------------------------------------------------------

Diff for: regex/inc-filename/REFERENCES.md

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
- [How to Generate unique file names in C# - Stack Overflow](https://stackoverflow.com/questions/4657974/how-to-generate-unique-file-names-in-c-sharp)
2+
- [c# - Increment filename - Stack Overflow](https://stackoverflow.com/questions/3341252/increment-filename)
3+
- [C#: How would you make a unique filename by adding a number? - Stack Overflow](https://stackoverflow.com/questions/1078003/c-how-would-you-make-a-unique-filename-by-adding-a-number)
4+
- [c# - Is there an easy way to add (#) to a filename when you find a duplicate filename? - Stack Overflow](https://stackoverflow.com/questions/1174640/is-there-an-easy-way-to-add-to-a-filename-when-you-find-a-duplicate-filename)
5+
- [File name copy algorithms - Stack Overflow](https://stackoverflow.com/questions/2184896/file-name-copy-algorithms)
6+
7+
- [Comparing strings, c++ - Stack Overflow](https://stackoverflow.com/questions/24957965/comparing-strings-c)
8+
9+
- [c++11 - Is there any benefit to to define constant local variables as static ( c++)? - Software Engineering Stack Exchange](https://softwareengineering.stackexchange.com/questions/350501/is-there-any-benefit-to-to-define-constant-local-variables-as-static-c)
10+
11+
- [Easiest way to convert int to string in C++ - Stack Overflow](https://stackoverflow.com/questions/5590381/easiest-way-to-convert-int-to-string-in-c)
12+
- [How to convert string to int and int to string in C++ - SysTutorials](https://www.systutorials.com/131/convert-string-to-int-and-reverse/)
13+
14+
- [string - How can I extract the file name and extension from a path in C++ - Stack Overflow](https://stackoverflow.com/questions/4430780/how-can-i-extract-the-file-name-and-extension-from-a-path-in-c)
15+
- [c++ - Easy way to remove extension from a filename? - Stack Overflow](https://stackoverflow.com/questions/6417817/easy-way-to-remove-extension-from-a-filename)
16+
17+
- [std::filesystem::path::stem - cppreference.com](https://en.cppreference.com/w/cpp/filesystem/path/stem)
18+
- [std::filesystem::path::extension - cppreference.com](https://en.cppreference.com/w/cpp/filesystem/path/extension)
19+
20+
- [operator+ (string) - C++ Reference](http://www.cplusplus.com/reference/string/string/operator+/)
21+
22+
- [How to copy a string into a char array in C++ without going over the buffer - Stack Overflow](https://stackoverflow.com/questions/2889421/how-to-copy-a-string-into-a-char-array-in-c-without-going-over-the-buffer)
23+
24+
- [Библиотека регулярных выражений — cppreference.com](https://ru.cppreference.com/w/cpp/regex)
25+
- [Регулярные выражения в C++11 и парсинг логов Nginx | Записки программиста](https://eax.me/cpp-regex/)
26+
- [std::regex_replace - cppreference.com](https://en.cppreference.com/w/cpp/regex/regex_replace)
27+
- [c++ - C++11 regex: digit after capturing group in replacement string - Stack Overflow](https://stackoverflow.com/questions/29809811/c11-regex-digit-after-capturing-group-in-replacement-string)
28+
- [regex_replace in C++ | Replace the match of a string using regex_replace - GeeksforGeeks](https://www.geeksforgeeks.org/regex_replace-in-cpp-replace-the-match-of-a-string-using-regex_replace/)
29+
- [c++ - std::regex_replace does not take fewer than 6 arguments - Stack Overflow](https://stackoverflow.com/questions/21858799/stdregex-replace-does-not-take-fewer-than-6-arguments)
30+
- [c++ - How do I use regex_replace? - Stack Overflow](https://stackoverflow.com/questions/24990646/how-do-i-use-regex-replace/24990964#24990964)
31+
- [Регулярные выражения — Википедия](https://ru.wikipedia.org/wiki/%D0%A0%D0%B5%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D0%B5_%D0%B2%D1%8B%D1%80%D0%B0%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F#%D0%96%D0%B0%D0%B4%D0%BD%D0%B0%D1%8F_%D0%B8_%D0%BB%D0%B5%D0%BD%D0%B8%D0%B2%D0%B0%D1%8F_%D0%BA%D0%B2%D0%B0%D0%BD%D1%82%D0%B8%D1%84%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D1%8F)
32+
33+
- [c++ - Using shared_ptr with char* - Stack Overflow](https://stackoverflow.com/questions/43631415/using-shared-ptr-with-char)
34+
- [c++ - shared_ptr to an array : should it be used? - Stack Overflow](https://stackoverflow.com/questions/13061979/shared-ptr-to-an-array-should-it-be-used)
35+
36+
- [c++ - Passing an array by reference - Stack Overflow](https://stackoverflow.com/questions/5724171/passing-an-array-by-reference)
37+
- [c++ - Counte elements (size) of array of objects - Stack Overflow](https://stackoverflow.com/questions/6947400/counte-elements-size-of-array-of-objects)
38+
- [Does C++ support constant arrays of type string? - Stack Overflow](https://stackoverflow.com/questions/2185443/does-c-support-constant-arrays-of-type-string)
39+
40+
- [File Name Hashing: Creating a Hashed Directory Structure](https://medium.com/eonian-technologies/file-name-hashing-creating-a-hashed-directory-structure-eabb03aa4091)

Diff for: regex/inc-filename/main.cpp

+135
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
#include <iostream>
2+
#include <string>
3+
#include <sstream>
4+
#include <regex>
5+
#include <cstdlib>
6+
#include <cstring>
7+
8+
enum CopyType : unsigned short int {
9+
FromSameFolder,
10+
FromAnotherFolder
11+
};
12+
13+
template<typename T, size_t N>
14+
size_t ArraySize(T(&)[N]) {
15+
return N;
16+
}
17+
18+
std::string files[] = {
19+
"example.txt"
20+
21+
// Что происходит при copy-paste одного и того же файла в одной и той же папке:
22+
, "example — копия.txt"
23+
, "example — копия 2.txt"
24+
, "example — копия 4.txt"
25+
, "example — копия 40.txt"
26+
, "example — копия 100.txt"
27+
, "example — копия 100500.txt"
28+
29+
// Что происходит при copy-paste файла из другой папки в папку, где уже есть
30+
// файл с таким именем:
31+
, "example 2.txt"
32+
, "example 3.txt"
33+
, "example 5.txt"
34+
, "example 40.txt"
35+
, "example 100.txt"
36+
, "example 100500.txt"
37+
38+
, "another.txt"
39+
40+
, "two.txt"
41+
, "two — копия.txt"
42+
43+
, "t 3.txt"
44+
45+
// Скопировать example.txt два раза в одной папке.
46+
// Скопировать example — копия 2.txt в другую папку.
47+
// Скопировать обратно.
48+
, "example — копия 2 2.txt"
49+
50+
, "b копия 2.txt"
51+
, "b копия 2 2.txt"
52+
53+
};
54+
55+
std::string GetExtensionFromFileName(const std::string &filename) {
56+
size_t lastdot = filename.find_last_of(".");
57+
if (lastdot == std::string::npos)
58+
return "";
59+
return filename.substr(lastdot);
60+
}
61+
62+
std::string RemoveExtensionFromFileName(const std::string &filename) {
63+
size_t lastdot = filename.find_last_of(".");
64+
if (lastdot == std::string::npos)
65+
return filename;
66+
return filename.substr(0, lastdot);
67+
}
68+
69+
template<size_t N>
70+
bool Exists(std::string filename, std::string (&filelist)[N]) {
71+
for (size_t i = 0; i < N; ++i)
72+
if (filename == filelist[i])
73+
return true;
74+
return false;
75+
}
76+
77+
template<size_t N>
78+
std::string MakeFileName(std::string filename, std::string (&filelist)[N], CopyType type) {
79+
static const std::regex PATTERN_DUPLICATE(R"(^(.* — копия)( ?)(\d*)$)");
80+
static const std::regex PATTERN_COPY(R"(^(.*?)( ?)(\d*)$)");
81+
82+
const std::regex &pattern = type == FromSameFolder ? PATTERN_DUPLICATE : PATTERN_COPY;
83+
std::smatch match;
84+
85+
std::string ext = GetExtensionFromFileName(filename);
86+
std::string resultname = RemoveExtensionFromFileName(filename);
87+
88+
if (Exists(filename, filelist)) {
89+
if (type == FromAnotherFolder) {
90+
resultname += " 2";
91+
} else if (type == FromSameFolder) {
92+
if (!std::regex_search(resultname, match, pattern)) {
93+
resultname += " — копия";
94+
}
95+
}
96+
} else {
97+
return filename;
98+
}
99+
100+
int i = 2;
101+
while (Exists(resultname + ext, filelist)) {
102+
if (std::regex_search(resultname, match, pattern)) {
103+
const std::string num = match[3];
104+
if (!num.empty()) ++i;
105+
std::stringstream replace;
106+
replace << "$1 " << i;
107+
resultname = std::regex_replace(resultname, pattern, replace.str());
108+
}
109+
}
110+
111+
return resultname + ext;
112+
}
113+
114+
int main(int argc, const char * argv[]) {
115+
std::cout << "" << std::endl;
116+
117+
assert("example — копия 3.txt" == MakeFileName("example.txt", files, FromSameFolder));
118+
assert("example — копия 3.txt" == MakeFileName("example — копия 3.txt", files, FromSameFolder));
119+
assert("example — копия 3.txt" == MakeFileName("example — копия 4.txt", files, FromSameFolder));
120+
121+
assert("unique.txt" == MakeFileName("unique.txt", files, FromSameFolder));
122+
assert("another — копия.txt" == MakeFileName("another.txt", files, FromSameFolder));
123+
assert("two — копия 2.txt" == MakeFileName("two.txt", files, FromSameFolder));
124+
125+
assert("t 3 2.txt" == MakeFileName("t 3.txt", files, FromAnotherFolder));
126+
127+
assert("example — копия 2 2 — копия.txt" == MakeFileName("example — копия 2 2.txt", files, FromSameFolder));
128+
assert("example — копия 2 2 2.txt" == MakeFileName("example — копия 2 2.txt", files, FromAnotherFolder));
129+
assert("b копия 2 3.txt" == MakeFileName("b копия 2.txt", files, FromAnotherFolder));
130+
131+
assert("example 4.txt" == MakeFileName("example.txt", files, FromAnotherFolder));
132+
assert("example 5 2.txt" == MakeFileName("example 5.txt", files, FromAnotherFolder));
133+
134+
return EXIT_SUCCESS;
135+
}

Diff for: regex/inc-filename/run.sh

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#!/bin/bash
2+
3+
EXE_FILE="./program.out"
4+
[ -f "$EXE_FILE" ] && rm "$EXE_FILE"
5+
clang++ --std=c++17 `find . -maxdepth 1 -name "*.cpp" | tr '\n' ' '` -o "$EXE_FILE" && "$EXE_FILE"

0 commit comments

Comments
 (0)