Превращение масок в регулярные выражения

2011-02-04

Иногда нужно реализовать понимание программным кодом масок, указанных пользователем. Под масками понимается, какой-то фрагмент теста в котором символ «*» означает любое количество любых символов, а символ «?» — означает один любой символ.
Примеры:
маска для поиска файлов («*.txt» — все текстовые файлы);
маски слов («*дом*» — все слова, содержащие фрагмент «дом»);
маски URL («http://web.izjum.com/*» — все страницы на сайте «http://web.izjum.com»);
маски IP-адресов («192.168.???.???»)
и много чего другого.

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

Сделать это можно так:

  • 1) экранируем слешом («\») служебные символы
    (такие как: «\», «#», «|», «(«, «)», «[«, «]», «{«, «}», «^», «$», «+», «.»);
  • 2) заменяем служебные символы маски на соответствующие аналоги в регулярных выражениях
    («*» заменяем на «.*», a «?» — на «.»);
  • 3) добавляем символы начала и конца строки
    («^» и «$» соответственно).

Реализация идеи представлена на языке программирования JavaScript:

function maskToRegExp(str) {
// реализация вспомагательной функции для замены всех найденных подстрок в строке
function replaceAll(str, what, to) {
return str.split(what).join(to);
}
// Присваиваем в качестве результата маску
var res = str;
// Этап 1: экранируем служебные символы
var arr = ["\\", "#", "|", "(", ")", "[", "]", "{", "}", "^", "$", "+", "."];
var len = arr.length;
for(var i=0; i<len; i++) {
res = replaceAll(res, arr[i], "\\"+arr[i]);
}
// Этап 2: заменяем служебные символы маски
// на соответствующие аналоги в регулярных выражениях
res = replaceAll(res, "*", ".*");
res = replaceAll(res, "?", ".");
// Этап 3: добавляем символы начала и конца строки
return "^"+res+"$";
}

Пример использования:

var myUrlRegExp = maskToRegExp("http://mysite.com/*");
// myUrlRegExp = "^http://mysite\.com/.*$";
var myPhoneRegExp = maskToRegExp("123-??-67");
// myPhoneRegExp = "^555-..-55$";
var myFileRegExp = maskToRegExp("report*.txt");
// myFileRegExp = "^report.*\.txt$";



3 комментария на «Превращение масок в регулярные выражения»

  1. Гость:

    ну и нафига эти очень полезные маски? читай glob.c, юзай линукс

  2. admin:

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

    Или среднестатистическому юзеру сразу мануал о регулярных выражениях показывать?

  3. на c# та же задача описана здесь [url=http://stud-work.ru/index.php/maska-fajla-s-pomoshchyu-regulyarnykh-vyrazhenij]Маска файла с помощью регулярных выражений[/url]

Добавить комментарий