2009-11-09 5 views
0

Я создаю механизм лексического анализа в C#. По большей части это делается и работает достаточно хорошо. Одна из особенностей моего lexer заключается в том, что он позволяет любому пользователю вводить собственные регулярные выражения. Это позволяет движку лексиковать всевозможные забавные и интересные вещи и выводить токенизированный файл.Можно ли отрицать поиск регулярных выражений?

Одна из проблем, возникающих у меня, заключается в том, что я хочу, чтобы у пользователя было все, что содержится в этом токенизированном файле. I.E части, которые они ищут, и части, которые они не являются (наглядным примером этого является Partial Highlighting).

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

Так что если пользователю захотелось использовать строку lex для каждого вхождения «T», то в отрицательной версии все было бы найдено, кроме «T».

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

+0

Это будет примером регулярных выражений х, которые будут использоваться, ( \? s +) каждый может иметь только одну именованную ссылку. – deanvmc

+0

Когда что-то считается токеном? Например, возьмите строку '" aaa bbb ccc "' и регулярное выражение '' a {2} | b {3} "', тождество '' bbb ''должно, вероятно, быть проигнорировано, но как насчет' aaa? '? Широкий конкретный пример поможет: прямо сейчас ваш вопрос оставляет слишком много для размышлений. –

+0

Подумайте об этом на этих условиях, Вы используете лексер, чтобы выделить код C#, поэтому вы разрабатываете 10 регулярных выражений, которые выделяют разные части кода. Это оставило бы вас с деталями, которые, возможно, не нужно выделять, или частями, которые вы намеренно не хотели выделять. Теперь движок создает файл-токен, содержащий всю строку, часть, которая является токенированной, и часть, которая не означает, что вам не нужно знать исходную конструкцию строк, вы можете просто проанализировать файл в безопасности, зная, что детали, нуждающиеся в синтаксическом анализе, будут анализировать другие, и это будет выглядеть правильно. – deanvmc

ответ

1

Вы можете объединить несколько RegEx-х в 1 с помощью (образцу pattern1) | (pattern1) | ... Отрицать это просто проверить IsMatch

var matches = Regex.Matches("aa bb cc dd", @"(?<token>a{2})|(?<token>d{2})"); 

вернется на самом деле 2 фишки (обратите внимание, что! Я дважды использовал одно и то же имя .. это нормально) Также изучите Regex.Split. Например:

var split = Regex.Split("aa bb cc dd", @"(?<token>aa bb)|(?:\s+)"); 

возвращает слова в качестве маркеров, для «аа бб», который возвращается в качестве одного маркера, потому что я определил это как так с (...?) Кроме.

Вы также можете использовать свойства Index и Length, чтобы вычислить средние части, которые не были признаны в Regex:

var matches = Regex.Matches("aa bb cc dd", @"(?<token>a{2})|(?<token>d{2})"); 
for (int i = 0; i < matches.Count; i++) 
{ 
    var group = matches[i].Groups["token"]; 
    Console.WriteLine("Token={0}, Index={1}, Length={2}", group.Value, group.Index, group.Length); 
} 
+0

Это очень хорошо. +1 к вам. – David

+0

Будет ли эта работа признана, что я использую названные ссылки для вытаскивания деталей, сложных выражений? – deanvmc

+0

DeanMc: да .. он должен работать. Я добавил несколько примеров в свой ответ. – Nestor

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