#javascript #regex
#javascript #регулярное выражение
Вопрос:
Мне нужно написать регулярное выражение для использования в обеспечении отсутствия коллизии имен файлов.
Итак, я даю пользователю возможность сохранить как некоторое имя, а затем я сравниваю строку с массивом, и если возникает коллизия, я следую парадигме сохранения Windows.
Если вы сохраните test
, это будет сохранено как test
, если вы попытаетесь сохранить test
снова, это станет test (1)
. Теперь я хочу посмотреть, что (1)
так
Условия
оно всегда будет начинаться с (
, а затем с N количеством символов 0-9 и заканчивается на )
.
Как я мог бы искать (1)
or (169)
с помощью регулярных выражений?
Я не уверен, что это минимальное количество символов, в котором я могу записать это регулярное выражение. Также в качестве дополнительного регулярного выражения, как бы я мог иметь то же самое, но также искать то же регулярное выражение, но с пробелом перед (
?
Попытка:
То, что я придумал, const regEx = RegExp(/(?:()[0-9*](?:))/)
однако это работает только для (1)
, но не (11)
и я не знаю, как также искать пробел перед (
Вероятно, это очень просто, но я не очень разбираюсь в регулярных выражениях.
Примеры строк, которые должны / не должны работать
// Should work:
test (1)
test (594)
test (54)
// Shouldn't work
test (1
test 594)
test 54
Комментарии:
1.
[0-9]
, не[0-9*]
…2. Обычно полезно, если вы включаете несколько примеров строк, которые должны совпадать, и строк, которые не должны совпадать.
3. @benvc верно, я должен был сделать это более явным и разделенным и привести больше примеров.
Ответ №1:
Строка должна заканчиваться на space(one or more digits)endOfString
, чтобы вы могли:
s((d ))$
дополнительные скобки (группа захвата) вокруг d
предназначены для извлечения числа:
https://regex101.com/r/5OFix0/1
Сопоставление
const sample = `test (0)
test (12)
test()
test(1)
test 1
ends with space (123) `;
sample.split('n').forEach(fileName => {
const m = /s((d ))$/.exec(fileName);
if (m amp;amp; m[1]) { // if is incremented, AKA "fileName (n)"
console.log(m[1]); // do your stuff here using m[1] string
}
});
Сопоставление и замена
Вот пример, в котором приведены примеры имен файлов (без расширений):
/**
* Detect " (n)" suffixed string. Return "n"
* @param {String} name
* @return {String|null} The integer string or null
*/
const isFilenameIncremented = name => {
const m = /s((d ))$/.exec(name);
return m amp;amp; m[1];
};
/**
* Increment unsuffixed or " (n)" suffixed string
* @dependency {Function} isFilenameIncremented
* @param {String} name
* @return {String} The " ((n|0) 1)" suffixed filename
*/
const incrementFilename = name => {
const isInc = isFilenameIncremented(name);
return isInc ? name.replace(/d (?=)$)/, m => ( m) 1) : `${name} (1)`;
}
const sample = `test (0)
test (12)
test()
test(1)
test 1
ends with space (123) `;
sample.split('n').forEach(filename => {
const fileNameIncr = incrementFilename(filename);
console.log( fileNameIncr )
});
Которое должно увеличивать только два первых имени файла (от 0 до 1 и от 12 до 13) и добавлять (1)
ко всем остальным, что приводит к следующему:
test (1)
test (13)
test() (1)
test(1) (1)
test 1 (1)
ends with space (123) (1)
Очевидно, что выше все еще не хватает проверки, существует ли это имя файла уже в массиве имен файлов, что может быть легко достигнуто с помощью fileNamesArray.includes(fileName)