Rambler's Top100
"Knowledge itself is power"
F.Bacon
Поиск | Карта сайта | Помощь | О проекте | ТТХ  
 Круглый стол
  
Правила КС
>> Настройки

Фильтр вопросов
>> Новые вопросы
отслеживать по
>> Новые ответы

Избранное

Страница вопросов
Поиск по КС


Специальные проекты:
>> К л ю к в а
>> Г о л о в о л о м к и

Вопрос №

Задать вопрос
Off-topic вопросы

Помощь

 
 К н и г и
 
Книжная полка
 
 
Библиотека
 
  
  
 


Поиск
 
Поиск по КС
Поиск в статьях
Яndex© + Google©
Поиск книг

 
  
Тематический каталог
Все манускрипты

 
  
Карта VCL
ОШИБКИ
Сообщения системы

 
Форумы
 
Круглый стол
Новые вопросы

 
  
Базарная площадь
Городская площадь

 
   
С Л С

 
Летопись
 
Королевские Хроники
Рыцарский Зал
Глас народа!

 
  
ТТХ
Конкурсы
Королевская клюква

 
Разделы
 
Hello, World!
Лицей

Квинтана

 
  
Сокровищница
Подземелье Магов
Подводные камни
Свитки

 
  
Школа ОБЕРОНА

 
  
Арсенальная башня
Фолианты
Полигон

 
  
Книга Песка
Дальние земли

 
  
АРХИВЫ

 
 

Сейчас на сайте присутствуют:
 
  
 
Во Флориде и в Королевстве сейчас  03:03[Войти] | [Зарегистрироваться]
Ответ на вопрос № 83826

05-10-2022 13:59
Добрый день, камрады, прошу помощи.
  Вопрос по сути ерундовый, но бывает ведь - и такое попадается ...
  Нужно решить задачу сортировки имен кучи файлов по критерию их соответствия заданному текстовому шаблону на основе регулярных выражений.
  В Дельфи имеется модуль Masks, в котором реализованы класс TMask и функция MatchesMask(const Filename, Mask: string): Boolean;
Оба объекта работают без проблем, по ним вопросов нет. Но споткнулся на ерунде - нигде не могу найти вменяемого и полного описания синтаксиса регулярных выражений для данных объектов. Требуется по возможности полное описание синтаксиса регулярных выражений и всех их параметров именно для данного модуля ! Поскольку, как я понимаю, оные регулярные выражения с параметрами для разных реализаций различаются, и немало.
  Хелп Дельфи у меня не запускается, так что есть ли там подобное описание - не знаю. Гугл выдает огрызки описаний синтаксиса регулярных выражений для самых разных реализаций, но только не для этой.
  Может, у кого-нибудь найдется текст с нужным описанием или ссылка на таковое ?
  А с другой стороны - могут ли регулярные выражения для сторонних реализаций подойти в данном случае ?

[+] Добавить в избранные вопросы

Отслеживать ответы на этот вопрос по RSS

Ответы:


Уважаемые авторы вопросов! Большая просьба сообщить о результатах решения проблемы на этой странице.
Иначе, следящие за обсуждением, возможно имеющие аналогичные проблемы, не получают ясного представления об их решении. А авторы ответов не получают обратной связи. Что можно расценивать, как проявление неуважения к отвечающим от автора вопроса.

14-10-2022 02:21 | Сообщение от автора вопроса
Вы от меня личное сообщение получили через систему внутрисайтовых личных сообщений? В правом верхнем углу жёлтый конвертик мигает? А то движок Королевства барахлит, и непонятно, ушло сообщение или нет.

  Угу, совершенно верно, барахлит ...Ваше сообщение нашел, написал ответ, нажал кнопку ... и не понял - то ли отправилось к вам, то ли улетело в никуда ...
Получили мой ответ или нет ????

Детальный ответ позже (возможно, не сегодня, ибо пятница :-))

  А я и забыл, что сегодня пятница. Сгораю на рабочем месте ... )))
В самом деле, торопиться некуда ... Как в классике :

                    Ямщик, не гони лошадей !
                    Мне некуда больше спешить,
                    Мне некого больше любить ...


Так что торопиться не будем ...
А за помощь и желание помочь огромное спасибо !!!

14-10-2022 01:09
Вы от меня личное сообщение получили через систему внутрисайтовых личных сообщений? В правом верхнем углу жёлтый конвертик мигает? А то движок Королевства барахлит, и непонятно, ушло сообщение или нет.
По остальному. Помогу, чем смогу. Только оперативность не гарантирую.
Детальный ответ позже (возможно, не сегодня, ибо пятница :-))

14-10-2022 00:23 | Сообщение от автора вопроса
С документацией всё обстоит либо слишком хорошо, либо слишком плохо.

  Ситуацию с документацией понял. Жаль, конечно ... Но ладно уж, как-нибудь переварим. Где наша не пропадала ...

Насколько я успел пока что бегло прошмонать функцию TRegEx.IsMatch( ... ) из модуля System.RegularExpressions.pas, работает она совершенно корректно, меня устраивает ... Вполне возможно, что удастся только ею и ограничиться ...
  Ваши примеры тоже понял. К сожалению, дело не ограничивается только такими простейшими случаями ... Ладно уж, попытаюсь изложить здесь попроще ту задачу, которая стоит у меня.

  Имеем огромную массу файлов в самых разнообразных форматах - текстовые документы, изображения, видео, сонограммы ... Расширения у файлов - самые разные, хотя общее их количество ( расширений ) довольно ограничено. Имена файлов включают два поля - <имя автора> и <Наименование документа>, отделенные друг от друга полем <разделитель>. Кроме этих трех полей возможно присутствие в имени других лексем, условно именуемых <мусор>.
  В поле <Наименование документа> может присутствовать информация, кратко характеризующая контент документа.
    Порядок следования двух основных лексем может быть прямым и обратным :
                    <имя автора><разделитель><Наименование документа> ...
              или  <Наименование документа><разделитель><имя автора>
    В качестве <разделитель> могут быть : пробел, подчеркивание, дефис, запятая ... что там еще ? Или их комбинации, например  " - " ,  "_-_"  ... человечья фантазия неограничена ...
  Кроме того, - и это очень существенно ! - во всех полях могут быть элементарные орфографические ошибки, возникающие по причине невнимательности при беглой печати ! Как то : пропуски символов, вставки лишних паразитных символов, подмены символов. Последнее - хуже всего : одно дело, если подмена наблюдаема ( символы совершенно разные по написанию ), а другое, если подменяются, скажем, символы кириллицы совершенно идентичными им по написанию символами латиницы ...

  Требуется :
    Реализовать поиск по именам файлов по каким-либо критериям с выводом в качестве результата множества файлов, имена которых удовлетворяют этим критериям.
В качестве критериев могут быть :
  авторы;
  все документы с заданными полями <имя автора> и <Наименование документа> с учетом различного порядка их следования;
  темы документов ( по краткой информации в поле <Наименование документа> ) ... возможны и более сложные критерии.

  Не подумайте только, что я пытаюсь переложить на вас решение этой своей задачи, но мне просто любопытно - что бы вы здесь применили ? Тем более, что я начал заниматься регулярными выражениями только что, и пока плохо соображаю, куда ворочать надо ...

13-10-2022 14:30
Виноват-с... Фигню спорол-с...
RegExpr.pas — это регулярные выражения Андрея Сорокина (самая популярная дельфийская библиотека по регекспам пока не сделали родную дельфийскую). А в дистрибутив входит именно System.RegularExpressions.pas. Если вам нужна просто функция проверки (аналог MatchesMask), то самый простой вариант будет выглядеть как-то так:

if TRegEx.IsMatch(FileName, Mask) then ...


или, если нужна регистронезависимость, то так:

if TRegEx.IsMatch(FileName, Mask, [roIgnoreCase]) then ...



Пример с конкретными выражениями.

if TRegEx.IsMatch(FileName, 'Дел\w+\.txt') then ...


Это выражение отфильтрует имена файлов, которые начинаются на "Дел" (именно с большой буквы), за которыми следует один или более символов, являющихся буквой (не уверен насчет русских букв), цифрой или подчерком, а дальше — точка и "txt".
То есть пройдут:
Дело.txt
Дел_25.txt
Дел3z.txt

Не пройдут:
дело.txt  - с маленькой буквы
Дел.txt  - нет ни одного символа между "Дел" и ".txt"
Дел2-5.txt  - между "Дел" и ".txt" есть символ минус, не являющийся буквой, цифрой или подчерком.

С документацией всё обстоит либо слишком хорошо, либо слишком плохо. Изначально регулярные выражения появились, вроде бы, в языке Perl, и та реализация является своего рода эталоном. А также существует куча реализаций для других языков, в которых синтаксис выражений в большей или меньшей степени соответствует перловскому. По стандарту Perl документацию найти не проблема, а вот по конкретной реализации для конкретного языка программирования полной документации может и не быть. Поэтому приходится брать какую-то и проверять, что из этого в используемой библиотеке есть, а чего нет. Я в качестве справочника по синтаксису регулярных выражений пользуюсь хелпом от упомянутой выше библиотеки Андрея Сорокина. Там не всё, что может быть, но основное описано. Да вам, собственно, и не обязательно изучать регулярные выражения в полном объеме, достаточно того, что позволит решить задачу.

13-10-2022 04:37 | Сообщение от автора вопроса
Я не понял, зачем вы используете маску, в которой определяете множество из одного символа? Ведь такая маска
[M]*
и такая
M*
Дадут один и тот же результат.


  Я просто привел чисто демонстрационный пример с чисто демонстрационными целями ... Так что не воспринимайте слишком уж всерьез. С другой стороны - если оба эти выражения совершенно идентичны по смыслу, то и результаты должны выдавать идентичные, так ведь ?

Почему нет разницы между большими и маленькими буквами, я уже писал: там всё приводится к верхнему регистру, а только потом сравнивается.
Но приведение к верхнему регистру выполняется только для символов от латинского алфавита a до z (см. реализацию функции UpCase), поэтому для русских букв большие и маленькие буквы различаются.


  Спасибо, понял ... Я всегда имел мрачные подозрения насчет того, что борландовские халтурщики в своем рвении не уступают микрософтовским ...

Про косяки с русскими буквами в масках для Delphi XE. Там всё просто. Код написан для старых версий Delphi, в которых тип Char однобайтовый. А множество символов в маске сохраняется в переменной паскалевского Set-типа. В Delphi XE тип Char стал двухбайтовым, но ыет-тип может быит только для однобайтовых типов, поэтому производится усекновение двухбайтового WideChar до однобайтового AnsiChar (там даже комментарий имеется, что WideChar Reduced to ByteChar in set expressions, и отключение соответствующего варнинга при компиляции). И если для латинских букв и символов первой половины таблицы это проходит корректно, то для остальных — нет. Если использовать просто символ без множества (то есть без квадратных скобок), то все работает как и в Delphi 7.

  Спасибо, это тоже понятно. Модуль Nask использовать нельзя  ни - ни ... ( См. далее ).

Если вам для вашей задачи достаточно функционала масок, то поправить (переделать) модуль Masks.pas, чтобы работал корреткно, либо написать свой.

  Да ну его ... Такой мутней заниматься ...

Например, в Delphi XE 3 входит RegExpr.pas, в котором имеется функция ExecRegExpr — аналог использованной вами MatchesMask.

  В Embarcadero RAD Studio 10 Delphi такого модуля - RegExpr.pas - нет. Зато нашелся другой - System.RegularExpressions.pas с классом TRegEx - как раз то, что нужно. Работает, кстати, совершенно корректно ( в том числе и с приведенными примерами ). А вот функции ExecRegExpr вообще нигде нет. Ладно, переживем ...

Но регулярные выражения существенно сложнее масок, с ними надо будет разбираться.

О - о - о, вот здесь-то мы и приходим к началу всех начал, с которого и начали свое начало - нужна документация по регулярным выражениям ... )))

13-10-2022 01:39
Я не понял, зачем вы используете маску, в которой определяете множество из одного символа? Ведь такая маска
[M]*
и такая
M*
Дадут один и тот же результат.

Почему нет разницы между большими и маленькими буквами, я уже писал: там всё приводится к верхнему регистру, а только потом сравнивается.

Но приведение к верхнему регистру выполняется только для символов от латинского алфавита a до z (см. реализацию функции UpCase), поэтому для русских букв большие и маленькие буквы различаются.

Про косяки с русскими буквами в масках для Delphi XE. Там всё просто. Код написан для старых версий Delphi, в которых тип Char однобайтовый. А множество символов в маске сохраняется в переменной паскалевского Set-типа. В Delphi XE тип Char стал двухбайтовым, но ыет-тип может быит только для однобайтовых типов, поэтому производится усекновение двухбайтового WideChar до однобайтового AnsiChar (там даже комментарий имеется, что WideChar Reduced to ByteChar in set expressions, и отключение соответствующего варнинга при компиляции). И если для латинских букв и символов первой половины таблицы это проходит корректно, то для остальных — нет. Если использовать просто символ без множества (то есть без квадратных скобок), то все работает как и в Delphi 7.

Что делать вам. Если вам для вашей задачи достаточно функционала масок, то поправить (переделать) модуль Masks.pas, чтобы работал корреткно, либо написать свой. Если функционала файловых масок недостаточно, смотрите регулярные выражения. Например, в Delphi XE 3 входит RegExpr.pas, в котором имеется функция ExecRegExpr — аналог использованной вами MatchesMask. Но регулярные выражения существенно сложнее масок, с ними надо будет разбираться.

12-10-2022 01:35 | Сообщение от автора вопроса
Geo,
С данном модулем случае не получится. Он существенно регистронезависимый. Вот так заносятся символы в набор символов в маске

        LastChar := UpCase(P^);
        CharSet := CharSet + [LastChar];

А вот так выполняется проверка на соответствие символа из имени файла

msSet: if not (FMaskStates[I].Negate xor (UpCase(P^) in FMaskStates[I].CharSet^)) then Exit;

То есть, строя структуру под маску, мы туда заносим не сам символ, а символ, приведенный к верхнему регистру. И проверяем мы не сам символ из имени файла, а символ, приведенный к верхнему регистру. В Windows имена файлов регистронезависимые, поэтому, подозреваю, так и было реализовано.
Примеры кода взяты из Delphi XE 3, но в других версиях вряд ли что-то принципиально изменилось.


  С модулем Nasks ( класс TMask и функция MatchesMask ) дело обстоит интереснее.
Состряпал простейший проект с этими объектами в Delphi 7, а затем без каких-либо изменений перетранслировал его в Embarcadero RAD Studio 10 Delphi. И в обоих вариантах попробовал простейший тест на множестве из 4-х файлов :

Mask.txt
mask_.txt
Дел.txt
дел_.txt


  ( имена 1-го и 2-го файла - в латинице, 3-го и 4-го - в кирилице ).
Результаты такие :
  В Embarcadero RAD Studio 10 Delphi -
  по маске [M]* выделяются первый и второй файлы;
  по маске [m]* выделяются тоже первый и второй файлы;
  по маске [Д]* и по маске [д]* не выделяется ничего;

  В Delphi 7 -
  по маске [M]* выделяются первый и второй файлы;
  по маске [m]* выделяются тоже первый и второй файлы;
  по маске [Д]* выделяется третий файл;
  по маске [д]* выделяется четвертый файл;
  Интересный результат ... В Delphi 7 с кириллическими именами работает, все-таки, правильно ...

Если вам недостаточно данного механизма масок, используйте настоящие регулярные выражения. Благо, в нынешних версиях Delphi они имеются, так что не придется искать сторонние библиотеки.
  А какие компоненты, классы, функции ( кроме Masks ) работают с регулярными выражениями ?

11-10-2022 22:47
>>> Например, ума не приложу, как при помощи этих шаблонов решить такой пустяковый вопрос, как установить / убрать для символов чувствительность к регистру символа ( реагирует, если в позиции только строчный или только прописной символ, или в позиции может быть как строчный, так и прописной символ ) ... Вообще-то, решение есть - [a-zA-Z] ( что-то в таком роде, могу ошибаться ), но такое решение не нравится ...
С данном модулем случае не получится. Он существенно регистронезависимый. Вот так заносятся символы в набор символов в маске

        LastChar := UpCase(P^);
        CharSet := CharSet + [LastChar];


А вот так выполняется проверка на соответствие символа из имени файла

msSet: if not (FMaskStates[I].Negate xor (UpCase(P^) in FMaskStates[I].CharSet^)) then Exit;


То есть, строя структуру под маску, мы туда заносим не сам символ, а символ, приведенный к верхнему регистру. И проверяем мы не сам символ из имени файла, а символ, приведенный к верхнему регистру. В Windows имена файлов регистронезависимые, поэтому, подозреваю, так и было реализовано.
Примеры кода взяты из Delphi XE 3, но в других версиях вряд ли что-то принципиально изменилось.

Если вам недостаточно данного механизма масок, используйте настоящие регулярные выражения. Благо, в нынешних версиях Delphi они имеются, так что не придется искать сторонние библиотеки.

10-10-2022 00:11 | Сообщение от автора вопроса
извините, что вас отвлёк своей писаниной ;-)
  Да нет, почему ... Вашу "писанину" прочел с большим удовольствием ... ))) Всегда приятно обнаружить человека, которого интересуют точно такие же проблемы ...

Вдруг появились какие-то новые регулярные выражения, которые выдают количественное значение совпадения строки с шаблоном.
  Я тоже очень рассчитываю именно на это. Но, к сожалению, выясняется, что это не так ...

С другой стороны, я (заворожённый словосочетанием "регулярные выражения") ... приготовился к обсуждению регулярных выражений.
  Если вас это и в самом деле интересует, то давайте обсудим, не возражаю. Тем более, что для своих задач я как раз весьма затрудняюсь построить адекватные регулярные выражения.

А тут оказывается просто поиск файла по маске.
  В том-то и дело, что не просто поиск файла по маске ... Задача формулируется сложнее. Пример одной из задач - имеется большое количество файлов, имена которых прямо или косвенно отражают их контент ( содержимое файла ). Нужно на основе регулярных выражений для имен файлов сформировать запрос, который выделит множество файлов с нужным контентом. Учитывая, что имена файлов сформированы с некоторыми искажениями ( иногда очень даже существенными ).

Спасибо за приведенные wildcards ( шаблоны поиска ), хотя они мне и хорошо известны. К сожалению, они недостаточны, хотелось бы больше ... Например, ума не приложу, как при помощи этих шаблонов решить такой пустяковый вопрос, как установить / убрать для символов чувствительность к регистру символа ( реагирует, если в позиции только строчный или только прописной символ, или в позиции может быть как строчный, так и прописной символ ) ... Вообще-то, решение есть - [a-zA-Z] ( что-то в таком роде, могу ошибаться ), но такое решение не нравится ...

09-10-2022 11:02
Вообще-то, я не наехать хотел, а разобраться. Вдруг появились какие-то новые регулярные выражения, которые выдают количественное значение совпадения строки с шаблоном. Выяснилось, что это не так, а просто вы неудачно сформулировали свой вопрос, что ввело меня в заблуждение. И это недопонимание очень быстро прояснилось. С другой стороны, я (заворожённый словосочетанием "регулярные выражения") не обратил внимания ни на название модуля, ни на название функции, и приготовился к обсуждению регулярных выражений. Отсюда мой интерес к тому, что именно вы собираетесь выявлять. Потому что регулярки интересны сами по себе. А тут оказывается просто поиск файла по маске.

>>> Мне надо всего лишь иметь под рукой полное описание синтаксиса регулярных выражений и всех их параметров для модуля Masks. Или ссылка на подобное описание. Если у вас таковые имеются и вы готовы поделиться - буду рад и признателен.
И вот это тоже сбило с толку. Я привык, что люди приходят на Круглый Стол за помощью в решении задач по программированию, а не задач по поиску документации.

В интересующем же вас модуле все просто. Классические wildcards:
* - любая последовательность любых символов
? - один любой символ
И есть еще множество символов — последовательность символов, заключённая в квадратные скобки. Допустимы также диапазоны символов, задающиеся как начальный и конечный символ диапазона, между которыми стоит знак минус
Пример:
[ace] — допускаются символы "a", "c" и "e".
[a-ce] — допускаются символы "a", "b", "c" и "e".
Восклицательный знак в первой позиции — отрицание. То есть:
[!a-ce] — допускаются любые символы кроме "a", "b", "c" и "e".
Что ещё... Сравнение регистронезависимое. Вот в принципе и всё, больше там ничего нет. Юнит Masks маленький, и там всё достаточно просто.

Но если вам нужна именно оформленная документация да ещё и из авторитетного источника, то тогда извините, что вас отвлёк своей писаниной ;-)

06-10-2022 23:01 | Сообщение от автора вопроса
В данном контексте не совсем понятен смысл слова "сортировка".
  Все мы люди-человеки со всеми недостатками и слабостями ... И я, как и любой другой человек, далеко не всегда имею возможность предельно четко сформулировать свои мысли. Поэтому не стоит излишне придираться к словам и терминам ...
  Ну хорошро, пусть будет не "сортировка", а будем использовать слово "фильтрация" - в смысле разделения текстовых строк на два множества - соответствующие регулярному выражению или не соответствующие. Или просто скажем - разделение на два множества ...
А такого, что "эта строка соответствует регулярному выражению больше, чем та" — такого нет.
  Простите, а где вы у меня увидели такое выражение : "эта строка соответствует регулярному выражению больше, чем та" ???

Ну и, если можно пример имен файлов, и чему они должны соответствовать.
  Если уж рассуждать вообще, то соответствовать они должны самым разным критериям отбора. Их много, все здесь не перечислишь ...
Но суть моего вопроса не в этом. Каким образом решать задачу, что и как делать - это я знаю. Мне надо всего лишь иметь под рукой полное описание синтаксиса регулярных выражений и всех их параметров для модуля Masks. Или ссылка на подобное описание. Если у вас таковые имеются и вы готовы поделиться - буду рад и признателен.

06-10-2022 15:22 | Вопрос к автору: запрос дополнительной информации
В данном контексте не совсем понятен смысл слова "сортировка". Текстовая строка либо соответствует регулярному выражению, либо не соответствует. А такого, что "эта строка соответствует регулярному выражению больше, чем та" — такого нет. Или под сортировкой все же понимается разделение на две кучки: соответствующие и несоответствующие?

Ну и, если можно пример имен файлов, и чему они должны соответствовать.

Добавьте свое cообщение

Вашe имя:  [Войти]
Ваш адрес (e-mail):На Королевстве все адреса защищаются от спам-роботов
контрольный вопрос:
Какой месяц идет после марта?
в качестве ответа на вопрос или загадку следует давать только одно слово в именительном падеже и именно в такой форме, как оно используется в оригинале.
Надоело отвечать на странные вопросы? Зарегистрируйтесь на сайте.
Тип сообщения:
Текст:
Жирный шрифт  Наклонный шрифт  Подчеркнутый шрифт  Выравнивание по центру  Список  Заголовок  Разделительная линия  Код  Маленький шрифт  Крупный шрифт  Цитирование блока текста  Строчное цитирование
  • вопрос Круглого стола № XXX

  • вопрос № YYY в тесте № XXX Рыцарской Квинтаны

  • сообщение № YYY в теме № XXX Базарной площади
  • обсуждение темы № YYY Базарной площади
  •  
     Правила оформления сообщений на Королевстве

    Страница избранных вопросов Круглого стола.
      
    Время на сайте: GMT минус 5 часов

    Если вы заметили орфографическую ошибку на этой странице, просто выделите ошибку мышью и нажмите Ctrl+Enter.
    Функция может не работать в некоторых версиях броузеров.

    Web hosting for this web site provided by DotNetPark (ASP.NET, SharePoint, MS SQL hosting)  
    Software for IIS, Hyper-V, MS SQL. Tools for Windows server administrators. Server migration utilities  

     
    © При использовании любых материалов «Королевства Delphi» необходимо указывать источник информации. Перепечатка авторских статей возможна только при согласии всех авторов и администрации сайта.
    Все используемые на сайте торговые марки являются собственностью их производителей.

    Яндекс цитирования