2012-06-20 5 views
0

Я работаю над некоторым приложением для моей магистерской диссертации, и в процессе работы я должен построить SQL Parser. Чтобы сделать это, я решил тяжело повторить, так как это кажется лучшим способом в то время.Выбор шаблона сложного регулярного выражения

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

Учитывая некоторые примеры запросов, таких как:

select 
    RIC 
from 
    (select 
     s.RIC, m.NAME 
    from 
     Stock s, Market m 
    where 
     s.LISTED_ON_EXCHANGE = m.RIC) t 
where 
    RIC > 'G'; 

select * 
from Stock 
order by COMPANY 
LIMIT 0,2; 

select 1+2; 

select now(); 

select 
    s.RIC, m.NAME 
from 
    Stock s 
INNER JOIN 
    Market ON m I s.LISTED_ON_EXCHANGE = m.RIC; 

select * 
from Stock 
order by COMPANY; 

select * 
from Stock 
where RIC in ('GS.N' , 'INFY.BO'); 

select * 
from Stock 
where RIC LIKE 'V%'; 

select * 
from Stock 
where RIC BETWEEN 'G' AND 'I'; 

select count(*) 
from STOCK 
where LISTED_ON_EXCHANGE IS NOT NULL; 

select na_me as n, price as p 
from bla, blabla, blalalaa; 

И дал следующие два регулярных выражений:

SELECT_FIELDS_PATTERN = "(?<=[SELECT]) [\\d\\w',.*() ]+ (?=FROM)"; 

Это должно соответствовать поля выбора.

И:

SELECT_FROM_PATTERN = "(?<=[FROM]) [\\w, ]+ (?(?=(?:WHERE|INNER|ORDER)))"; 

Это должно соответствовать ОТ положений, исключающих какие-либо условия или упорядочения и т.д.

Все запросы, кроме

select 1+2; 
select now(); 

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

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

select na_me as n, price as p from bla, blabla, blalalaa; 

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

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

select RIC from (select s.RIC, m.NAME from Stock s, Market m where s.LISTED_ON_EXCHANGE=m.RIC) t where RIC > 'G'; 

Вывод должен быть:

РИК

для первой части и

(выберите s.RIC, m.NAME из Стоковые с, Market м, где s.LISTED_ON_EXCHANGE = m.RIC) т

для второй части

+1

Если упражнение само по себе не является написанием парсера, не хотите ли вы использовать что-то вроде antlr и определенной (sql) грамматики? http://www.antlr.org/grammar/list – Glenn

+0

@ Glenn Я никогда не рассматривал этот вариант раньше, но это действительно могло помочь –

+0

@Glenn Я не уверен, можете ли вы использовать antlr для извлечения данных в POJO, например формат. Я хотел бы иметь, например, такую ​​структуру, как: SelectDTO (корневой объект), который имеет getFromClause(), getWhereClause() и т. Д., И, например, каждый из них может также возвращать SelectDTO, поскольку запросы рекурсивные –

ответ

2
  • Классы символов не являются группами - удалить [ & ] вокруг ключевых слов.
  • Не используйте бесполезные образы, это может привести к проблемам в некоторых случаях.
  • Возможно, вы захотите использовать \b вокруг ключевых слов, чтобы SELECT не соответствовал FOOSELECT.
  • Может использовать (?i), чтобы сделать регистр выражения нечувствительным.

Вы могли бы использовать что-то вроде:

(?i)\bSELECT\b\s+(.+)\s+\bFROM\b\s+([\w\s,]+?)(?:\s+\b(?:WHERE|INNER|ORDER)\b|;?$) 

с частями интереса захватывается в первой и второй группы захвата.

Обратите внимание, что это не будет работать правильно со строками, а в других случаях также рекурсивно SQL, что довольно сложно разобрать с регулярным выражением Java. Я предлагаю вам использовать правильный парсер, если вы хотите правильно проанализировать SQL. (Вы можете написать простой, используя regex для лексинга, генерирующего токены и Java, для анализа токенов и построения дерева синтаксического анализа.)

+0

Спасибо за совет я обязательно буду учитывать это. Но регулярное выражение все равно не будет соответствовать общим выборам: SELECT * FROM FOO; –

+0

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

+0

@BogdanEmilMariesan, см. Обновление. – Qtax

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