2010-11-01 4 views
3

Преобразование старой программы в сайт ASP.NET C#.Быстрая строка с подстановочным знаком

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

Например:.

V(totalValue) * V(CoFriction(s)) ==> V("totalValue") * V("CoFriction(s)") 

Как я могу заменить V(<variable>) на V("<variable>"). Вложенные скобки возможны!

Я пробовал regexp like - V\([^\(\)]+\) только для отказа на вложенном паре.

+1

Ну, если вложенные скобки разрешены/возможны, как бы вы определили, когда значение является строковым литералом, а когда нет? Что это значит, когда функция, которая должна рассматриваться как строковый литерал, имеет другую функцию как параметр, который также должен рассматриваться как строковый литерал? Мне кажется, что вам нужно написать простой рекурсивный синтаксический анализатор спуска, который, как только он найдет имя функции, о котором он знает, начинает скобки, до тех пор, пока не будет найдена закрывающая скобка, и окружает весь участок с помощью перевернутых запятых. В противном случае вам придется оценивать именованные функции во время выполнения. – Kell

ответ

2

Вы можете achive его в .net с помощью балансировки группы:

string s = "V(totalValue) * V(CoFriction(s)) * V(a(()b)c()d((())))"; 

string vPattern = 
@"V\(
(  #capturing group, for $1 to work 
    (?: 
     (?<open>\()| #push to stack OR 
     (?<-open>\))| #pop from stack OR 
     [^()]   #match anything else 
    )+? 
) 
(?(open)(?!)) #assert there are not extra (
\)"; 

s = Regex.Replace(s, vPattern, "V(\"$1\")", RegexOptions.IgnorePatternWhitespace); 

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

+0

Ничего себе, я узнал что-то новое :) Но yikes, я не уверен, что когда-либо буду использовать это! – Kell

+0

@ Kell - Спасибо. Эта нотация, характерная для .Net и вне досуга, используется только ограниченно, но она хорошо подходит для этого случая - она ​​позволяет захватывать сбалансированные маркеры, но не захватывать каждую отдельную пару круглых скобок. Конечно, нетрудно подсчитать скобки вручную, что является допустимым решением. – Kobi

1

Я так построил библиотеки, как это в прошлом. Функция Regex, которую вы хотите, называется «балансировочные группы». Там хорошая рецензия на http://blog.stevenlevithan.com/archives/balancing-groups Я думаю, что вы хотите что-то вроде этого:

V\((?>[^()]+|\((?<Depth>)|\) (?<-Depth>))*(?(Depth)(?!))\) 

Если я правильно помню, это будет по существу добавить скобку на «Глубину» стек, когда он видит под открытую скобку, удалите его из " Глубина ", когда он видит близкий паз (если в стеке нет ни одного), а затем отказ открытого пара не закрывается.

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