2010-08-31 2 views
4

Учитывая следующие регулярные выражения:Определение специфичности регулярного выражения

- [email protected][a-z]+\.[a-z]+ 
- [a-z][email protected][a-z]+\.[a-z]+ 
- .* 

Строка [email protected] будет, очевидно, совпадают все три регулярные выражения. В приложении, которое я разрабатываю, нас интересует только «наиболее конкретный» матч. В этом случае это, очевидно, первый.
К сожалению, похоже, что нет способа сделать это. Мы используем PCRE, и я не нашел способ сделать это, и поиск в Интернете также не был плодотворным.
Возможным способом было бы сохранить регулярные выражения, отсортированные по нисходящей специфике, а затем просто взять первое совпадение. Конечно, следующий вопрос: как отсортировать массив регулярных выражений. Это не вариант, чтобы дать ответчику конечный пользователь, чтобы убедиться, что массив отсортирован. Итак, я надеюсь, вы, ребята, могли бы помочь мне здесь ...

Спасибо!

Пол

+1

Для меня не очевидно, что первый из них является «самым конкретным». Какое ваше определение «наиболее специфическое» определяет алгоритм для этого, и вы будете на полпути. Но мне кажется, что это простой способ сделать это (например, Flex) - у вас есть несколько выражений, которые точно совпадают, а затем выбирают первый, определенный в ваших данных. –

ответ

4

Моя интуиция говорит, что это не только сложная проблема, как с точки зрения вычислительных затрат и сложности реализации, но это может быть неразрешимой в любой реалистической манере. Рассмотрим два следующих регулярных выражений, чтобы принять строковое [email protected]

 
    [email protected][a-z]+\.[a-z]+ 
    [a-z][email protected]

Какой из них более конкретно?

+0

Тот, у кого больше символьных констант? Или, может быть, вы можете автоматически создать регулярное выражение, которое было пересечением их обоих. То есть, если RE (a) определяет язык L1 и RE (b) определяет язык L2, постройте регулярное выражение RE (a, b), которое определяет язык INTERSECTION (L1, L2). – Avi

5

Я работаю над ответом на одной и те же проблемы, что я нашел до сих пор находится здесь: http://maple.cs.umbc.edu/~don/projects/ugrad-ht/dminer-ugradthesis.pdf

Это исследование уровня выпускницы бумага, используя PERL регулярного выражения, то есть работоспособное определение для «наиболее специфичных regex 'и вызывает предупреждение, если есть два выражения регулярных выражений с одинаковой специфичностью. Он частично основан на установочном файле SELinux, но имеет целью быть более быстрым и точным. Setfile оставляет его пользователю, чтобы совпадения переходили от наиболее специфических к наименее конкретным и принимали первое совпадение. Это может вызвать некоторые проблемы, которые исследовательский документ должен решить.

В принципе, наиболее конкретный матч - это тот, который не является надмножеством любого другого матча. Сложность решения заключается в определении того, какие множества являются надмножествами других множеств; конечно, ответ на это зависит от обстоятельств, для которых требуется регулярное выражение. Когда у вас есть список надмножеств, тогда это становится вопросом устранения совпадений. Таким образом, с выражениями регулярных выражений '^ /. *', '^/Usr /.*' и '^/home /.*', '^ /. *' Является надмножеством двух других, а остальные два взаимно эксклюзив. В правильной реализации, если два вторых не были взаимоисключающими (отсутствует «^»), и ни один из них не является надмножеством другого, пользователю или пользователю должно быть выдано предупреждение или ошибка. Для данной строки, чтобы проверить соответствие, сначала ее нужно проверить против любых надмножеств (в данном случае «^ /. *»), Если она не соответствует надмножеству, она не может соответствовать какому-либо конкретному шаблону. Если он соответствует, тогда должен выполняться тест против каждого из дочерних элементов надмножества (эти наборы также могут быть надмножествами дополнительных наборов). Если он не соответствует ни одному из детей, то наиболее конкретным регулярным выражением является надмножество ('^ /. *'). Если он соответствует одному из детей, то процесс должен повториться с ассоциированными внуками, пока не будет никаких конкретных наборов или ни один из конкретных наборов не будет соответствовать.

Может быть достаточно, чтобы не выдавать предупреждения о не взаимоисключающих не супер-наборах, если не выполняется попытка сопоставления строк, которая не может быть разрешена. Рассмотрим множество выражений регулярных выражений: '^ /. *', '/usr.*' и '/home.*'. Строка '/ home/usr' будет соответствовать всем трем, и попытка совпадения должна вызвать ошибку, так как неясно, если '/usr.*' или '/home.*' предназначено как наиболее конкретный регулярный выражение.

В зависимости от причин, требующих решения, верным списком регулярных выражений, которые не являются надмножествами любого другого подходящего регулярного выражения, может быть идеальным решением. В этом случае '/ home/usr' должен возвращать '/home.*' и '/usr.*', но не '^ /. *'.

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

+0

Погружаясь на сайт автора, я нашел это: это не GPLed, поэтому не используйте его, не связываясь с ним в первую очередь. http://maple.cs.umbc.edu/~don/projects/ugrad-ht/regexfind.py – Perkins

+0

указанные URL недействительны –

0

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

Решение, однако, было бы просто отсортировать список регулярных выражений в порядке его длины строки.

Это не идеально, но просто удалив [] -группы, это будет намного ближе. На первом примере в этом вопросе было бы этот список:

- [email protected][a-z]+\.[a-z]+ 
- [a-z][email protected][a-z]+\.[a-z]+ 
- .* 

к этому, после удаления содержимого любого [] -группа:

- [email protected]+\.+ 
- [email protected]+\.+ 
- .* 

То же самое касается второго примера в другом ответе, с [] -групп полностью удалены и сортируются по длине, так:

[email protected][a-z]+\.[a-z]+ 
[a-z][email protected] 

стал бы отсортированный как:

[email protected] 
[email protected]+\.+ 

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