2010-06-05 4 views
2

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

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

  2. Это расширение предыдущей проблемы. Предположим, что у меня такая же ситуация: строка и список из N регулярных выражений, только теперь каждое из регулярных выражений сопряжено со смещением внутри строки, в которой должно начинаться совпадение (или, если хотите, каждое регулярное выражение должен соответствовать подстроке заданной строки, начинающейся с заданного смещения).

Для примера предположит, что у меня был строка:

This is a test string

и регулярные выражения модель и смещение:

(a) his.* at offset 0 
(b) his.* at offset 1

Алгоритм должны вернуть истинные. Хотя regex (a) не соответствует строке, начинающейся со смещения 0, regex (b) действительно соответствует подстроке, начинающейся со смещения 1 («его тестовая строка»).

Есть ли структура данных, которая может позволить мне решить эту проблему в сублинейное время?

Одним из полезных сведений является то, что часто многие смещения в списке регулярных выражений являются одинаковыми (например, мы часто используем подстроку со смещением X много раз). Это может быть полезно для решения проблемы проблемы № 1 выше.

Благодарим вас за любые предложения, которые могут возникнуть у вас!

+1

Какое подмножество регулярных выражений? Это всего лишь префиксный матч? В этом случае вы можете использовать дерево суффиксов. Однако сублинейный может быть слишком большим, чтобы просить об этом. Кроме того, какие изменения? Строка, подлежащая согласованию, или регулярные выражения? Или оба? – 2010-06-05 19:33:32

+0

Посмотрите похожие вопросы: http://stackoverflow.com/questions/2899800 –

+0

Спасибо за ваши ответы. Это не просто префиксное совпадение. Это прежде всего простые подстановочные знаки и классы символов, но они могут появляться где угодно (а не только префикс или суффикс). Регулярные выражения фиксируются при инициализации (во время выполнения), а строка, подлежащая согласованию, неоднократно изменяется в течение всей операции программы (программа получает новые строки для повторного сопоставления). – DSII

ответ

0

(1) Объединить все регулярные выражения как большой союз: (r1)|(r2)|(r3)|...

(2) Для каждого регулярного выражения с офсетных п добавить п точки начала плюс якорь. Таким образом, his.* со смещением 6 становится ^......his.*. Или, если ваш синтаксис regex поддерживает его, ^.{6}his.*.

2

Предполагаю, что у вас действительно есть сила регулярных выражений.

  1. Для того, чтобы определить, является ли строка соответствует одной из выражений e_1, e_2, ..., e_n, просто совпадают с выражением e_1 + e_2 + ... + e_n (иногда оператор + записывается в виде |).

  2. Указанные пары (e_1, o_1), ..., (e_n, o_n) выражение смещения и строка, вы можете проверить, есть ли i такое, что строка соответствует выражением e_i по смещению o_i путем сопоставления с выражением .{o_1}e_1 + ... + .{o_n}e_n.

В зависимости от формы отдельных выражений вы можете получить сублинейную производительность (не в целом, хотя).

+0

Я отвечу здесь, так как этот ответ проголосован, хотя ответы Христиан Semrau и Джон Kugelman ниже в основном то же самое. Прежде всего, спасибо всем вам за ваши ответы! Я ценю помощь. Я был бы удивлен, если бы это решение было практичным ... У меня создалось впечатление, что составление DFA из регулярного выражения занимало O (2 м) время и пространство для регулярного выражения длины m и с N ~ десятками из тысяч регулярных выражений для совпадения и смещения размером в несколько миллионов это казалось бы неуправляемым. Длина объединения регулярных выражений будет слишком огромной. Я ошибаюсь? – DSII

+0

Граница O (2^m) является наихудшей верхней границей, что дается конструкцией [powerset] (http://en.wikipedia.org/wiki/Powerset_construction). После нескольких применений этой конструкции к шаблонам подстановок (содержащих только «*» и «?» В качестве подстановочных знаков, что означает «. *» И «.?» Как регулярное выражение), мне кажется, что DFA имеет такое же количество состояний как NFA, который имеет несколько состояний, похожих на длину рисунка. Разумеется, объединение N таких DFA может очень хорошо экспонироваться при преобразовании в DFA. И начала смещения даже не рассматриваются. Итак, вы правы: здесь не работает метод автомата. –

+0

Еще раз спасибо за ответ. Я думаю, вы правы. Есть ли другая альтернатива наивному линейному поиску? – DSII

1

Если ваши выражения достаточно просты (шаблоны подстановочных знаков), И ваш набор выражений предопределен, т. Е. Изменяется только вход, который должен быть согласован, THEN вы можете построить finite state machine, который соответствует объединению ваших выражений, т. Е. выражение "(r1) | (r2) | ...".

Построение этой машины занимает время и пространство не менее O (N) (но я думаю, что это не экспоненциальный, что является наихудшим случаем для регулярных выражений вообще). Соответствие тогда 0 (длина (вход)), независимо от N.

OTOH, если ваш набор выражений должен быть частью ввода программы, тогда нет сублинейного алгоритма, просто потому, что нужно учитывать каждое выражение.

Смежные вопросы