2012-12-20 3 views
3

Мне нужно создать регулярное выражение для C#, чтобы захватить все имена таблиц, которые находятся после «из» ключевых слов в отдельных предложениях. НапримерКак получить все имена таблиц с регулярным выражением в C#?

. 
. 
. 
SELECT field1, field2 
FROM table1 
WHERE condition1 
. 
. 
. 
SELECT field3, field4 
FROM table2 
WHERE condition2 
. 
. 
. 

Есть несколько выберите пункты в файлах, которые я пытаюсь читать, и может быть любой символ между выбрать и из (в том числе новые линии, «:», «_» и любой другой символ) , Как мне создать регулярное выражение, чтобы получить все имена таблиц?

Благодаря

EDIT: Я обнаружил способ получить все имена таблиц.

\s*SELECT[^;]*FROM\s*(?<key>[^\n]*) 

Это может помочь кому-то в определенный день. Благодаря

+0

Когда я пытаюсь выполнить SELECT [\ D | \ d] * FROM (? [^ \ n] *) ', он находит одно совпадение, начинающееся с первого выбора и вплоть до последнего из. Вместо этого я хочу, чтобы он соответствовал всем выборам и возвращал все их имена таблиц. – Alpay

+0

Дайте сайту попробовать, всегда помогает мне при определении RegExes http://regexpal.com/ – Charleh

+0

@Charleh, который предназначен для регулярных выражений Javascript. Для .NET вы должны использовать [RegexHero] (http://regexhero.net) –

ответ

3

Если все запросы имеют только один стол, и комментариев нет, смешные дела с комментариями, использование регулярных выражений для этого - это потерянное предложение. Вместо этого:

SET SHOWPLAN_ALL ON; 

--All your queries here 

См. set showplan_all docs.

Когда я говорю, что регулярное выражение будет сложным, это то, что я имею в виду. Это лишь некоторые из соображений:

  • Вы должны обнаружить начало строк в кавычках: ", ' и [ и игнорировать все символы внутри, пока не будет прекращено надлежащим образом. Не завершайте, если символ конца удваивается (т. Е. 'this is ''fun'', he said' не останавливается после is).

  • Вы должны исключить однострочные комментарии --, которые не входят в кавычки, и завершают их на следующем CRLF. Котировки комментариев внутри комментариев не начинаются, как обычно.

  • Вы должны исключить многострочные комментарии (начиная с /*), которые не внутри кавычек или внутри одной строки комментария, а затем пропустить через все остальное, за исключением терминатора, */. В своем регулярном выражении обязательно избегайте символа * с обратной косой чертой \.

  • Вы должны затем найти действительные FROM пункты с надлежащими словоразделами (нет ложного матч на имена столбцов SelfRom или AfroMonkey, например).

  • Чтобы правильно завершить ЕК, вы должны остановить захват, когда вы видите любое ключевое слово, включая WHERE, GROUP BY, HAVING, ORDER BY и WITH; и так как запросы SQL не требуется, чтобы иметь точку с запятой терминатор ; Вам также придется прекратить в SELECT, DBCC, SET, CREATE, ALTER, DROP и так далее, и так далее.

  • Но даже предыдущие два очка не хватает на самом деле сами по себе, потому что, если ваш запрос выглядит следующим образом:

    SELECT * 
    FROM 
        MyTable T 
        INNER JOIN (
         SELECT * FROM YourTable Y WHERE Active = 1 
        ) X ON T.ID = Y.ID 
        INNER JOIN AnotherTable A 
         ON X.AID = A.AID 
    

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

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

Вот что я придумал, просто пытается обработать . Даже не цитирует. И это только доходит до определения от, а не того, что внутри него. Кроме того, мы должны предотвратить скобки скобок, поэтому у нас нет ужасного беспорядка при рассмотрении наших групп захвата для фактических предложений FROM.

(?:(?:-(?!-)|/(?!\*)|f(?!rom)|[^-f/])|--[^\n]*\n|/\*(?:\*/)*\*/)*from() 

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

Я думаю, что вы недооцениваете, насколько трудно достичь такой цели. Но есть совершенно надежное решение! Тот, который я дал выше: пусть SQL Server все анализирует для вас. Вы можете легко анализировать возвращенный план, потому что он структурирован таким образом, который облегчает его.

1

Для начала я бы сказал, что проверить этот учебник: http://www.codeproject.com/Articles/9099/The-30-Minute-Regex-Tutorial

ЗАКАНЧИВАТЬ регулярное выражение так: ((?<=FROM)[^\s]+)

Это регулярное выражение будет начать читать сразу после "FROM " (в том числе пробелов) и прекращает чтение на первый пробельные (^\s)

, если вы пытаетесь что-то вроде этого

foreach (Match m in Regex.Matches(input, @"((?<=FROM)[^\s]+)") 
{ 
    string output = m.Value; 
} 

EDIT:

Я не уверен в этом регулярном выражении на 100%. Если у вас есть символ новой строки в конце вашего имени, этот woudl, вероятно, сделает работу лучше: @"((?<=FROM)[^\n]+)), но вы, вероятно, должны обрезать вывод, поскольку в начале строки вывода может быть пробел.

+0

ФОРМА! == От моего дорогого парня – ErikE

+0

@ErikE Извините, неправильно прочитал, что .. изменен! – 2pietjuh2

0
var input = "select name from Table1 where id =2"; 
var pattern = @"from\s*(.*?)\s*where"; // where car= is the first delimiter and ; is the second one 
var result = Regex.Match(input, pattern).Groups[1].Value; 
MessageBox.Show(result); 
+0

А как насчет комментариев, которые говорят «от»? Катастрофа. – ErikE

+0

Несколько запросов вместе не будут обрабатываться правильно - результат будет охватывать все из них. – ErikE

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