#c# #regex
Вопрос:
Я создаю простое консольное приложение для домашнего проекта. В принципе, он отслеживает папку на предмет любых добавляемых файлов.
FileSystemWatcher fsw = new FileSystemWatcher(@"c:temp");
fsw.Created = new FileSystemEventHandler(fsw_Created);
bool monitor = true;
while (monitor)
{
fsw.WaitForChanged(WatcherChangeTypes.Created, 1000);
if(Console.KeyAvailable)
{
monitor = false;
}
}
Show("User has quit the process...", ConsoleColor.Yellow);
Когда поступают новые файлы, вызывается «WaitForChanges», и тогда я могу приступить к работе.
Что мне нужно сделать, так это проверить имя файла на наличие шаблонов. В реальной жизни я помещаю видеофайлы в эту папку. Основываясь на имени файла, у меня будут правила, которые перемещают файлы в определенные каталоги. Так что на данный момент у меня будет список пар значений ключей… держа регулярное выражение (я думаю?) и папку. Таким образом, если имя файла соответствует регулярному выражению, оно перемещает его в соответствующую папку.
Примером имени файла является:
CSI- NY.S07E01.The 34th Floor.avi
Итак, мое регулярное выражение должно посмотреть на него и посмотреть, существуют ли слова CSI «И» (Нью-Йорк»,» Нью-Йорк «ИЛИ» Нью-Йорк»). Если они это сделают, я затем перенесу их в SeriesCSINY
папку.
Мне нужно И, потому что другой пример файла для другой серии:
CSI- Crime Scene Investigation.S11E16.Turn On, Tune In, Drop Dead
Так что для этого мне нужно было бы иметь несколько «Нет». Итак, мне нужно проверить, есть ли в имени файла CSI, но НЕТ («Нью-Йорк», «Нью-Йорк» или «Нью-Йорк»)
Может ли кто-нибудь помочь мне с этими регулярными выражениями? Или, может быть, есть лучший метод?
Ответ №1:
Вы можете попробовать сохранить условия в Func<string,bool>
Dictionary<Func<string,bool>,string> dic = new Dictionary<Func<string, bool>, string>();
Func<string, bool> f1 = x => x.Contains("CSI") amp;amp; ((x.Contains("NY") || x.Contains("New York"));
dic.Add(f1,"C://CSI/");
foreach (var pair in dic)
{
if(pair.Key.Invoke("CSI- NY.S07E01.The 34th Floor.avi"))
{
// copy
return;
}
}
Ответ №2:
Я думаю, у вас есть правильная идея. Хорошая особенность этого подхода заключается в том, что вы можете добавлять/удалять/редактировать регулярные выражения в файл конфигурации или какой-либо другой подход, что означает, что вам не нужно перекомпилировать проект каждый раз, когда вы хотите отслеживать новое шоу.
Регулярное выражение для CSI И NY будет выглядеть примерно так. Сначала, если вы хотите проверить, существует ли CSI в имени файла, регулярное выражение просто "CSI"
. Имейте в виду, что по умолчанию он чувствителен к регистру. Если вы хотите проверить, существуют ли Нью-Йорк, Нью-Йорк или Нью-Йорк в имени файла, регулярное выражение "((NY)|(New York)|(NewYork))"
Столбики указывают ИЛИ, а скобки используются для обозначения групп. Чтобы объединить их, вы можете запустить оба регулярных выражения, и в некоторых случаях (где, возможно, порядок не имеет значения) это может быть проще. Однако, если вы всегда ожидаете, что тип show появится после синтаксиса, будет "(CSI).*((NY)|(New York)|(NewYork))"
Точка означает «любой символ», а звездочка означает ноль или более.
Комментарии:
1. Хммм.. На мой взгляд, я действительно не думаю, что регулярное выражение является лучшим вариантом в этом контексте 🙁
2. Возьмите количество, которое соответствует последовательно, я имею в виду, как бы вы выразились
str.Contains("A") amp;amp; str.Contains("B")
регулярным выражением?3. @Оскар — я тоже не уверен, что это так. Однако регулярные выражения полезны, и ОПЕРАЦИЯ права, по крайней мере, рассматривая их.
4. Не берите в голову. Я просто говорю, что для того, чтобы сделать что-то такое простое, как «A amp;amp; B», вам нужно будет проверить бота:
.*A.*B
и.*B.*A.*
или что-то в этом роде.
Ответ №3:
Это не выглядит как одно регулярное выражение, даже если вам удастся объединить все это в одно целое. Регексы, которые соответствуют «чему угодно без данного слова», — это боль. Мне лучше придерживаться двух регексов для каждого правила: один, который должен совпадать, и другой, который НЕ должен совпадать для срабатывания этого правила. Если вам нужны ваши «CSI» и «NY», но вам не нравится фиксировать какой-либо определенный порядок в имени файла, вы также можете переключиться с пары регулярных выражений на пару списков регулярных выражений. В общем, лучше вложить эту логику в код и конфигурацию и сохранить регексы как можно более простыми. И да, вам, скорее всего, сойдет с рук простой поиск по подстрокам, нет явной необходимости в регексах, пока вы сохраняете свой код достаточно умным.
Ответ №4:
Ну, люди уже дали вам несколько советов о том, как это сделать с помощью:
- Регулярные выражения
- Функция и сохранение именно того кода C#, который будет выполнен в файле
так что я просто дам тебе другой вариант.
Я не согласен с использованием регулярных выражений для этой цели. Я согласен с @Anton S. Kraievoy: мне не нравится, когда регулярные выражения соответствуют чему-либо без данного слова. Это проще проверить: !text.Contains(word)
Второй вариант выглядит идеально, если вы ищете быстрое решение, но…
Если это более сложное приложение, и вы хотите правильно его спроектировать, я думаю, вам следует:
- Определите, как вы будете хранить эти шаблоны (в классе с членами или в строке и т. Д.). Примером строки может быть:
"CSI" amp; ("NY" || "Las Vegas")
- Затем напишите модуль, который будет соответствовать имени файла с этим шаблоном.
Вы создаете своего рода DSL.
Почему это лучше, чем просто вставить непосредственно код C#?
Ну, потому что:
- Вы можете легко изменить семантику ваших шаблонов
- Вы можете сгенерировать код проверки на любом языке, который вам нужен, потому что вы храните шаблоны общим способом.
Дело в том, как сопоставить шаблон с именем файла.
У вас есть несколько вариантов:
- Напишите грамматику вашего шаблона и напишите синтаксический анализатор самостоятельно
- Сгенерируйте (я не уверен на 100%, что это возможно, это зависит от грамматики) регулярное выражение, которое преобразует вашу грамматику в код C#.
Например:"A" amp; "B"
кstring.Contains("A") amp;amp; string.Contains("B")
или что-то в этом роде. - Используйте для этого инструмент, например ANTLR.
Комментарии:
1. Спасибо Оскару Медеросу — это тоже очень хорошо… Вручную сделать это кажется достаточно простым… Спасибо.