Соответствующие подстановочные знаки
В информатике алгоритм сопоставления подстановочных знаков (также известный как подстановка ) полезен при сравнении текстовых строк, которые могут содержать синтаксис подстановочных знаков . [1] Обычное использование этих алгоритмов включает интерфейсы командной строки , например оболочку Bourne. [2] или Microsoft Windows командная строка [3] или текстовый редактор или файловый менеджер, а также интерфейсы для некоторых поисковых систем. [4] и базы данных. [5] Сопоставление по подстановочным знакам — это подмножество проблемы сопоставления регулярных выражений и сопоставления строк в целом. [6]
Проблема
[ редактировать ]Средство сопоставления подстановочных знаков проверяет шаблон подстановочных знаков p по входной строке s . Он выполняет привязанное сопоставление и возвращает true только тогда, когда p соответствует всему s .
Шаблон может быть основан на любом общепринятом синтаксисе (см. подстановку ), но программисты Windows обычно обсуждают только упрощенный синтаксис, поддерживаемый собственной средой выполнения C: [7] [8]
- Escape-символы не определены
- Подстановочные знаки:
?
соответствует ровно одному вхождению любого символа.*
соответствует произвольному количеству (включая ноль) вхождений любого символа.
В этой статье в основном обсуждается формулировка проблемы в Windows, если не указано иное.
Определение
[ редактировать ]Заявленная в индексах, отсчитываемых от нуля, проблема сопоставления подстановочных знаков может быть определена рекурсивно как:
где m ij — результат сопоставления шаблона p с текстом t, усеченным до символов i и j соответственно. Это формулировка, используемая алгоритмом Рихтера и алгоритмом фрагментов , найденным в коллекции Канаторе. [9] [10] Это описание похоже на расстояние Левенштейна .
Связанные проблемы
[ редактировать ]К непосредственно связанным проблемам информатики относятся:
- Сопоставление с образцом с безразличием или пробелами, поиск незакрепленной строки с использованием только эквивалента
?
определенный. [11] [12] - Сопоставление шаблонов с подстановочными знаками, поиск незакрепленной строки с определением эквивалента обоих подстановочных знаков. Имеет экспоненциальное время выполнения, если в варианте сопоставления шаблона с гибкими подстановочными знаками не указана привязка к длине. [13]
История
[ редактировать ]Ранние алгоритмы сопоставления подстановочных знаков часто основывались на рекурсии , но этот метод подвергался критике из-за производительности. [10] и надежность [8] соображения. В свете этих соображений популярность получили нерекурсивные алгоритмы сопоставления подстановочных знаков.
Как среди рекурсивных, так и нерекурсивных алгоритмов стратегии выполнения операции сопоставления с образцом сильно различаются, о чем свидетельствует разнообразие примеров алгоритмов, упомянутых ниже. Методы разработки тестовых примеров и оптимизации производительности явно применялись к определенным алгоритмам, особенно к тем, которые были разработаны критиками рекурсивных алгоритмов.
Рекурсивные алгоритмы
[ редактировать ]Рекурсия обычно происходит при сопоставлении *
когда есть больше суффикса для сопоставления. Это форма поиска с возвратом , также выполняемая некоторыми средствами сопоставления регулярных выражений.
- Rich Salt ( Алгоритм подстановочного мата синтаксис типа sh) [14]
- Алгоритм Филипа [15] и алгоритм Виньеша Муругесана [16]
- Алгоритм Мартина Рихтера [9] (идентично Snippets и связано с алгоритмом 7-zip) [17]
- Реализации библиотеки C fnmatch (поддерживает
[...]
и многобайтовые наборы символов):- Гвидо ван Россума , BSD libc fnmatch [18] также часть Apple libc [19]
- Glibc fnmatch [20]
Общий вид этих алгоритмов одинаков. При рекурсии алгоритм разбивает входные данные на подстроки и считает, что совпадение произошло, когда ОДНА из подстрок возвращает положительное совпадение. Для dowild("*X", "abcX")
, оно жадно позвонит dowild("X", "abcX")
, dowild("X", "bcX")
, dowild("X", "cX")
и dowild("X", "X")
. Обычно они отличаются менее важными вещами, такими как поддержка функций, и более важными факторами, такими как незначительные, но весьма эффективные оптимизации. Некоторые из них включают в себя:
- Сигнал ABORT против чрезмерной рекурсии (Ларс Матисен, 1991). Хотя правильно наивно рекурсивно использовать все остальные строки (шаблон и текст) на
*
и убедившись, что ОДНА из подстрок возвращает положительное совпадение, время выполнения становится экспоненциальным для отклонения совпадения со многими*
в тексте. Ларс Матисен меняет возврат на три класса: совпадение, несовпадение и ABORT (совпадение вообще невозможно для рекурсии звездочки). Значение ABORT возвращается, когда текст используется слишком рано или когда другое совпадение со звездочкой не удалось, гарантируя линейная производительность по отношению к количеству звездочек. (Общая сложность дополнительно квадратична количеству символов, которые осталось сопоставить.) [14] Подстановочное соответствие ABORT в Git/Rsync также распространяется на недопустимые входные данные. [21] Новый МНН uwildmat делает то же самое. [22] - Улучшение Asterisk в рекурсии. Эта настройка wildmatch относительно незначительна. Это применимо, когда рекурсия хочет сопоставить «*X» с «abcX»: когда за звездочкой следует литерал типа «X», очевидно, что только последнее сравнение с одинаковой длиной будет иметь шанс получить совпадение. . [21] Это было видно ранее в uwildmat в 2000 году. [22] и, более косвенно, в fnmatch ван Россума за
FNM_PATHNAME
.
Алгоритм Мартина Рихтера является исключением из этого шаблона, хотя в целом операция эквивалентна. При * происходит рекурсия к увеличению любого из индексов в соответствии с формулировкой задачи динамического программирования. К нему также применима методика «ABORT». [9] В типичных шаблонах (по результатам тестирования Cantatore) он медленнее, чем реализации жадного вызова. [10]
Рекурсивные алгоритмы, как правило, легче анализировать, и с модификацией ABORT они работают приемлемо с точки зрения сложности в наихудшем случае. В строках без * для сопоставления требуется время линейного размера строки, поскольку существует фиксированное отношение один к одному.
Нерекурсивные алгоритмы
[ редактировать ]Критики рекурсивных алгоритмов разработали следующие:
- Алгоритм Кирка Дж. Краусса сопоставления с подстановочными знаками , используемый IBM [8] [23]
- Коллекция алгоритмов сопоставления с подстановочными знаками Алессандро Канаторе [10]
- Итеративный сопоставитель Догана Курта и более медленный сопоставитель NFA. [17]
- Неправильный алгоритм Силера (не работает
MATCH("da*da*da*", "daaadabadmanda")
) [24]
Следующее не является:
- Неправильный алгоритм Джека Хэнди [25] (не удается
MATCH("*?", "xx")
)
Приведенные выше итерационные функции реализуют обратный поиск, сохраняя старый набор указателей на шаблон/текст и возвращаясь к нему в случае неудачного совпадения. По словам Курта, поскольку требуется только одно успешное совпадение, то и сохранить нужно только один такой набор. [17]
Кроме того, проблему сопоставления по подстановочным знакам можно преобразовать в сопоставление по регулярным выражениям, используя простой подход с заменой текста . Хотя нерекурсивные средства сопоставления регулярных выражений, такие как конструкция Томпсона, на практике используются реже из-за отсутствия поддержки обратных ссылок, сопоставление по подстановочным знакам в целом не обладает столь же богатым набором функций. (Фактически, многие из приведенных выше алгоритмов поддерживают только ?
и *
.) Реализация Расса Кокса Thompson NFA может быть тривиально модифицирована для этого. [26] Алгоритм nrgrep Густаво Наварро на основе BDM обеспечивает более упрощенную реализацию с упором на эффективные суффиксы. [27] См. также § Реализации регулярных выражений .
См. также
[ редактировать ]- Сопоставление с образцом
- Исчисление шаблонов
- Глоб (программирование)
- Подстановочный знак
- Список алгоритмов
Ссылки
[ редактировать ]- ^ «Подстановочные знаки» . НаукаДирект . 2018.
- ^ Куигли, Элли (2005). Краткое руководство по программированию в командной оболочке UNIX . ИнформИТ.com.
- ^ «Подстановочные знаки MS-DOS и Windows» . Сетевая библиотека разработчиков Microsoft .
- ^ «Apache Lucene — синтаксис анализатора запросов» . Документация Apache Lucene 2.9.4. 2006.
- ^ «Подстановочные знаки SQL» . W3Школы . 2018.
- ^ Гойвертс, Январь (2018). «Добро пожаловать на Regular-Expressions.info» . RegularExpressions.info.
- ^ «Расширение подстановочных знаков» . docs.microsoft.com .
- ^ Перейти обратно: а б с Краусс, Кирк (2008). «Сопоставление подстановочных знаков: алгоритм» . Журнал доктора Добба .
- ^ Перейти обратно: а б с Тупик (2015). «Рекурсивный алгоритм сопоставления подстановочных знаков C++» . Переполнение стека .
- ^ Перейти обратно: а б с д Канаторе, Алессандро (2003). «Алгоритмы сопоставления с подстановочными знаками» .
- ^ Илиопулос, Костас С.; Рахман, М. Сохель (2007). «Алгоритмы сопоставления шаблонов с безразличием» (PDF) . SOFSEM 2007: Теория и практика информатики, 33-я конференция по современным тенденциям в теории и практике информатики . Гаррахов, Чехия. S2CID 14538871 . Архивировано из оригинала (PDF) 17 декабря 2019 г.
- ^ Клиффорд, Питер; Клиффорд, Рафаэль (январь 2007 г.). «Простое детерминированное сопоставление с подстановочными знаками». Письма об обработке информации . 101 (2): 53–54. дои : 10.1016/j.ipl.2006.08.002 .
- ^ У, Синьдун; Цян, Цзи-Пэн; Се, Фэй (12 сентября 2014 г.). «Сопоставление шаблонов с гибкими подстановочными знаками». Журнал компьютерных наук и технологий . 29 (5): 740–750. дои : 10.1007/s11390-014-1464-3 . S2CID 16824910 .
- ^ Перейти обратно: а б Зальц, Рич (1991). "wildmat.c" . Гитхаб .
- ^ Филип (2014). «Сравнить строки с подстановочным знаком» . Переполнение стека .
- ^ Муругесан, Винеш (2014). «Алгоритм сопоставления подстановочных знаков» .
- ^ Перейти обратно: а б с Курт, Доган. «Методы сопоставления с подстановочными знаками» .
- ^ ван Россум, Гвидо (20 ноября 2019 г.). "freebsd/lib/libc/gen/fnmatch.c" . Гитхаб . Проверено 21 ноября 2019 г.
- ^ "fnmatch.c" . opensource.apple.com. 1999.
- ^ "fnmatch_internal.c" . Зеркала Берена Минора. 21 ноября 2019 г.
- ^ Перейти обратно: а б "git/git: wildmatch.c" . Гитхаб . 20 января 2020 г.
- ^ Перейти обратно: а б «uwildmat.c в багажнике/библиотеке — INN» . inn.eyrie.org . Проверено 27 ноября 2019 г. .
- ^ Краусс, Кирк (2018). «Сопоставление подстановочных знаков: улучшенный алгоритм для больших данных» . Развивайтесь ради производительности.
- ^ Силер (2013). «Рекурсивные решения для сопоставления шаблонов» . Переполнение стека .
- ^ Хэнди, Джек (2005). «Сравнение строк с подстановочными знаками (подстановка)» . Код проекта .
- ^ Кокс, Росс. «Сопоставление регулярных выражений может быть простым и быстрым» .
- ^ Наварро, Гонсало (10 ноября 2001 г.). «NR-grep: быстрый и гибкий инструмент сопоставления с образцом» (PDF) . Программное обеспечение: практика и опыт . 31 (13): 1265–1312. дои : 10.1002/сп.411 . S2CID 3175806 .