Комар на улице Вязов
О шмоньке Соловьеве, aka Вечерний Мудозвон и о накрутках.
Вместо преамбулы скажу сразу вывод, да Соловьева абсолютно законно выпиздил из трендов Ютуб. И абсолютно в соответствии со своими правилами. И зря Роскомнадзор запрещает аниме, т.к. им же реклама на некоторых аниме-сайтах просмотры и накручивает.
Итак, сижу я, никого не трогаю, новости на kasparov.ru читаю, вдруг вижу — Расчленинградский суд запретил аниме «Токийский взрыв» оно же «Террор в Токио» про подростков, которые сбежали от современной версии Отряда 731 и пытаются таки донести мысль, что нацисты не сдохли, и они даже есть в рядах японского правительства, и японские империалисты даже атомную бомбу втихую собрали. Так что вроде как и запрещать его не надо, все про крымнаш, антифашизм и даже деды воевале.
Сижу я, никого не трогаю, примус починяю , в смысле аниме смотрю, тут вдруг вижу вот это:

(полное разрешение)
Небольшое расследование
Оно совсем небольшое, но тем не менее. У плеера kodik.info, где он был внедрен на сайт каталога аниме, есть некая база аниме (что вообще так-то хорошо, информация должна быть свободной). Ну так вот, сайты с контентом не держат контент у себя, а подключают плеер, а плеер (точнее, хозяева плеера) показывают рекламу и аниме. А чтобы купить показ в плеере kodik, нужно потратить несколько мертвых президентов США. И, они не на хеллоуин, они на долларовых купюрах. Пока не буду говорить, как я купил рекламу у kodik.info, мы придержим. Но просьба распространить, чтоб у вечернего М. пукан подорвался. Так что Ютуб вполне норм выебал Соловьева, вечернего М. за накрутку.
Удачи вам и любви!
Пакетный конвертер (перекодировщик) текстовых файлов v 0.0.3b
Обновление пакетного конвертера текстовых файлов.
Благодарим всех, кто сообщил о багах.
+ Изменения в алгоритме поиска файлов
+ Поправлен баг с сохранением конфигурации (масок файлов)
C#, поиск файла по маске, более правильное решение.
Когда-то уже говорил (копия) что стандартная функция C# Directory.GetFiles();
неправильно ищет файлы по маске. И даже сделал на скорую руку кривофикс, но кривофикс действительно оказался именно что криво. Во-первых, срабатывал только для некоторых масок, а во-вторых, оказался чувствительным к регистру имен файлов. Делаем более прямое исправление.
Заведем вспомогательную функцию, которая будет добавлять конечный слэш (\
) к имени директории. Оно не особо надо, но пусть будет для порядка.
private static string AddSlash(string st) { if (st.EndsWith("\\")) { return st; } return st + "\\"; }
И функцию, получающую имя файла из полного пути. Конечно, можно было бы воспользоваться классом FileInfo
из System.IO
, но тут операция совсем уж простая, а FileInfo
может сгенерировать ненужный Exception
. Проще получить имя файла с помощью строковой операции:
private static string GetNameOnly(string FullName) { int LastSlash = FullName.LastIndexOf("\\"); if (LastSlash == -1) return FullName; return FullName.Substring(LastSlash + 1); }
Да, я таки решил воспользоваться нелюбимыми регекспами. Впрочем, маска файла и есть регулярное выражение, только с упрощенным синтаксисом.
1. В имени файла могут встретиться символы, считающиеся служебными в регулярном выражении (.
,^
,$
,{
,}
,[
,]
,(
,)
,+
), их необходимо экранировать, чтоб они воспринимались обработчиком регулярных выражений, как обычные, а не служебные символы.
//точка в маске файла должна быть точкой в регулярном выражении
//экранируем
Mask = Mask.Replace(".", "\\.");
//^,$,{,},[,],(,),+ в regexp служебные, в именах файла допустимые
//экранируем
Mask = Mask.Replace("^", "\\^");
Mask = Mask.Replace("$", "\\$");
Mask = Mask.Replace("{", "\\{");
Mask = Mask.Replace("}", "\\}");
Mask = Mask.Replace("[", "\\[");
Mask = Mask.Replace("[", "\\[");
Mask = Mask.Replace("(", "\\(");
Mask = Mask.Replace(")", "\\(");
Mask = Mask.Replace("+", "\\+");
2. *
— в маске файла это любой символ, или их отсутствие. В регулярном выражении этому соответствует комбинация .*
, заменяем:
Mask = Mask.Replace("*", ".*");
3. ?
в маске файла — любой существующий символ. В регулярном выражении это символ .
(точка), заменяем:
Mask = Mask.Replace("?", ".");
4. Осталось ограничить работу регулярного выражения началом и концом строки, строкой будет являться имя (маска) файла. Начало строки обозначается символом ^
, конец символом $
. Добавляем:
Mask = "^" + Mask + "$";
Функция целиком:
private static string Mask2Reg(string Mask) { //точка в маске файла должна быть точкой в регулярном выражении //экранируем Mask = Mask.Replace(".", "\\."); //^,$,{,},[,],(,),+ в regexp служебные, в именах файла допустимые //экранируем Mask = Mask.Replace("^", "\\^"); Mask = Mask.Replace("$", "\\$"); Mask = Mask.Replace("{", "\\{"); Mask = Mask.Replace("}", "\\}"); Mask = Mask.Replace("[", "\\["); Mask = Mask.Replace("[", "\\["); Mask = Mask.Replace("(", "\\("); Mask = Mask.Replace(")", "\\("); Mask = Mask.Replace("+", "\\+"); //* - любое количество любого символа, //в regexp любой символ - точка, любое количество * Mask = Mask.Replace("*", ".*"); //? - любой символ, в regexp любой символ - точка. Mask = Mask.Replace("?", "."); //добавляем начало и конец строки к имени файла. Mask = "^" + Mask + "$"; return Mask; }
В модифицированную функцию поиска передаются такие же параметры, как и в функцию Directory.GetFiles();
т.е. маска файла, путь до каталога и перечисление SearchOption
, которое может принимать два значения: SearchOption.AllDirectories
— поиск с подкаталогами и SearchOption.TopDirectoryOnly
— поиск только в текущем каталоге.
Внутри функции:
1. Преобразуем маску файла в регулярное выражение:
string MaskRegStr = Mask2Reg(sMask);
2. Добавляем слеш к пути поиска (на всякий случай):
sPath = AddSlash(sPath);
3. Заводим List<string>
, куда будем складировать отфильтрованные файлы из найденных (на то, как криво работает Directory.GetFiles()
есть ссылки в начале заметки).
List<string> FoundFiles = new List<string>();
4. Создаем обработчик регулярных выражений с опцией RegexOptions.IgnoreCase
, чтобы игнорировать регистр входной строки (в нашем случае — имени файла).
Regex MaskReg = new Regex(MaskRegStr, RegexOptions.IgnoreCase);
5. Вызываем функцию поиска из System.IO
:
string[] files = Directory.GetFiles(sPath, sMask, SO);
6. Фильтруем вывод на предмет лишних файлов (см. подробнее по ссылке в начале заметки). Фильтрация производится путем сравнения имени файла с ранее сгенерированным регулярным выражением. Если имя файла соответствует регулярке, оно добавляется в List
:
foreach (string filename in files) { if (MaskReg.IsMatch(GetNameOnly(filename))) { FoundFiles.Add(filename); } }
7. Результат возвращается в виде строкового массива:
return FoundFiles.ToArray();
Функция целиком:
public static string[] Find(string sPath, string sMask, SearchOption SO) { string MaskRegStr = Mask2Reg(sMask); sPath = AddSlash(sPath); List<string> FoundFiles = new List<string>(); Regex MaskReg = new Regex(MaskRegStr, RegexOptions.IgnoreCase); string[] files = Directory.GetFiles(sPath, sMask, SO); foreach (string filename in files) { if (MaskReg.IsMatch(GetNameOnly(filename))) { FoundFiles.Add(filename); } } return FoundFiles.ToArray(); }
Вроде бы в этот раз все предусмотрел, и глюкоопцию встроенной функции поправил, и в регулярке нигде не наебался.
Песня про НЛО.
Вспомнилась детская, почти крипи-стори. Итак, прикиньте, начало 90-х, по телеку идут 600 секунд и передача «НЛО — Необъявленный Визит» с Мягченковым. И вот, в садике я долго объяснял одногруппнику что НЛО существуют, и даже песня про них есть. Ее по радио передают.
Я даже сходил к воспитательнице и спросил, кто такая кавалер-барышня, поскольку в те годы транс было транспортным агентством, а трап — деталью от корабля, воспитательница мне рассказала историю про кавалерист-девицу, которая прикинулась парнем, чтобы пойти служить. Вот тут-то у меня все в голове окончательно сложилось, песня про НЛО:
Крутится-вертится шар голубой
Крутится-вертится над головой (НЛО же, иначе хуле ему вертеться)
Крутится-вертится, хочет упасть (приземляется)
Кавалер-барышню хочет украсть (хочет унести для исследований нетипичную девушку, которая хочет служить в армии).
Такие дела.