Regex для соответствия всем, кроме строки в кавычках в C # - PullRequest
3 голосов
/ 05 марта 2009

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

например. если у меня есть код, который выглядит так:

            while (t < 10)
            {
                string s = "get if stmt";
                u = GetVal(t, s);
                for(;u<8;u++)
                {
                    t++;
                }

            }

Я пытался использовать Regex как @ "(. *?) \ S (FOR | WHILE | IF) \ s" но это дает мне «если» в качестве следующего ключевого слова. тогда как я хочу получить следующее ключевое слово через некоторое время как «для», а не как «если», которое заключено в кавычки.

Можно ли это сделать в любом случае с помощью Regex? Или мне придется использовать обычное программирование?

Ответы [ 5 ]

2 голосов
/ 05 марта 2009

Попробуйте следующее RegEx ( Редактировать: исправлено).

(?:[^\"]|(?:(?:.*?\"){2})*?)(?: |^)(?<kw>for|while|if)[ (]

Примечание. Поскольку этот литерал RegEx содержит кавычки, перед строкой нельзя использовать знак @. Помните, что если вы добавите в строку какие-либо специальные символы RegEx, вам нужно будет дважды экранировать их приблизительно (например, \ w). Убедитесь, что вы также указали параметр Multiline при сопоставлении с RegEx, чтобы символ вставки (^) считался началом новой строки.

Это не было проверено, но должно делать эту работу. Дайте мне знать, если есть какие-либо проблемы. Кроме того, в зависимости от того, что еще вы хотите здесь сделать, я мог бы рекомендовать использовать стандартный синтаксический анализ текста (не-RegEx), поскольку он быстро станет более читабельным в зависимости от того, сколько данных вы хотите извлечь из кода. Надеюсь, это поможет в любом случае.

Edit: Вот пример кода, который я протестировал и уверен, что он работает как задумано.

var input = "while t < 10 loop\n s => 'this is if stmt'; for u in 8..12 loop \n}"; 
var pattern = "(?:[^\"]|(?:(?:.*?\"){2})*?)(?: |^)(?<kw>for|while|if)[ (]";
var matches = Regex.Matches(input, pattern);
var firstKeyword = matches[0].Groups["kw"].Value;
// The following line is a one-line solution for .NET 3.5/C# 3.0 to get an array of all found keywords.
var keywords = matches.Cast<Match>().Select(match => match.Groups["kw"].Value).ToArray();

Надеюсь, это будет ваше полное решение сейчас ...

1 голос
/ 05 марта 2009

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

0 голосов
/ 05 марта 2009

Можно ли это сделать в любом случае с помощью Regex?

В общем случае нет. Синтаксис C # не поддается регулярному анализу.

Рассмотрим эти угловые случаи:

method("xxx\"); while (\"xxx");

method(@"xxx \"); while (...);

// while

/* while */

/* xxx
// xxx */ while

/* xxx " xxx */ while ("...

Языки, такие сложные, как C #, требуют специальных синтаксических анализаторов.

0 голосов
/ 05 марта 2009

Я полагаю, Regex, не может легко понять ключевые слова C #. Я бы предложил вам использовать: Microsoft.CSharp.CSharpCodeProvider, с помощью этой Visual Studio управляет кодом C #.

0 голосов
/ 05 марта 2009

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...