Замена регулярных выражений C# с игнорированием совпадений, найденных в строковых кавычкахC#

Место общения программистов C#
Ответить Пред. темаСлед. тема
Anonymous
 Замена регулярных выражений C# с игнорированием совпадений, найденных в строковых кавычках

Сообщение Anonymous »

Я работаю в приложении, где системные администраторы могут создавать настраиваемые поля и настраивать вычисления для разрешения значений в этих полях. Эти вычисления сохраняются как строковое свойство объекта CustomField. Мне поручено провести массовую очистку этих вычислений, в основном сосредоточившись на замене функций и операторов конъюнкции на их сокращенные варианты. Я хочу использовать метод RegEx.Replace() для решения этой задачи в решении .NET C#.
Пример строки расчета (пользователи вводят Calc в синтаксисе VB.NET):
IIF([FIELD1] = "This and that" AND [FIELD2] = "This or that", "Value 1",
IIF ([FIELD3] = "This and that" OR [FIELD4] = "This or that", "Value 2",
""))

Требования задачи:
  • Замены: IIF -> IF, And -> AndAlso, Or -> OrElse
  • Поиски/совпадения не должны учитывать регистр для всех выполняемых замен, поскольку разные администраторы используют разный регистр при написании синтаксиса.
  • Для IIF функции, необходимо найти как "IIF(" (синтаксис с левой скобкой сразу после "F"), так и совпадение с любым переменным количеством пробелов между "F" и левой круглой скобкой. Это основано на наблюдениях за тем, как я я вижу расчеты, написанные в среде моего клиента.
  • Для обеих фраз И/ИЛИ необходимо найти экземпляры с начальным/конечным пробелом и убедиться, что фраза не является частью строки в кавычках. Таким образом, в приведенном выше примере строки расчета действительные операторы соединения будут заменены, но строки и/или в «Это и то» и «Это или это» будут проигнорированы и пропущены.
Ниже приведен пример того, что у меня есть в качестве отправной точки. Я считаю, что у меня правильный шаблон функции IIF, используя «альтернативный» | символ канала, чтобы выполнить сопоставление «или/или» для этой фразы, но я застрял в том, как настроить шаблоны «И/ИЛИ», чтобы исключить замену совпадений, содержащихся в строках.
foreach (CustomFieldInfo customField in Session.ConfigurationManager.GetCustomFields(false))
{
string fieldCalcStr = customField.Calculation.Trim();
if (string.IsNullOrEmpty(fieldCalcStr)) continue;
fieldCalcStr = Regex.Replace(fieldCalcStr, @"IIF\(|IIF *\(", "IF(", RegexOptions.IgnoreCase);
fieldCalcStr = Regex.Replace(fieldCalcStr, " AND ", " AndAlso ", RegexOptions.IgnoreCase);
fieldCalcStr = Regex.Replace(fieldCalcStr, " OR ", " OrElse ", RegexOptions.IgnoreCase);
customField.Calculation = fieldCalcStr;
}

ПРИМЕЧАНИЕ. Я видел здесь множество сообщений, в которых люди пытались выполнить что-то относительно похожее, но во всех случаях ответы были очень специфичны для входной строки, предоставленной OP, и сделал предположения, из-за которых предложенные ответы оказались неприменимыми к моему случаю пользователя и конкретным требованиям.
Любая помощь будет очень признательна.
* ** ОБНОВЛЕНИЕ ***
Мне удалось выяснить это, используя RegEx.Split() для возврата массива строк в кавычках и без кавычек в том же порядке, в котором они появляются в исходной строке, а затем просто выполните замену для каждого шаблона, если элемент массива не начинается с кавычки:
Dictionary patternReplacementDict = new Dictionary();
patternReplacementDict.Add("(?:IIF\\s*[(])", "IF(");
patternReplacementDict.Add("(?: AND )", " AndAlso ");
patternReplacementDict.Add("(?: OR )", " OrElse ");
foreach (CustomFieldInfo customField in Session.ConfigurationManager.GetCustomFields(false))
{
string calcStr = customField.Calculation.Trim();
if (string.IsNullOrEmpty(calcStr)) continue;
string[] calcStrArray = Regex.Split(calcStr, "(\"[^\"]+\")");
string newCalcStr = string.Empty;
foreach (string str in calcStrArray)
{
if (!str.StartsWith("\""))
{
string newStr = str;
foreach (KeyValuePair kvp in patternReplacementDict)
{
newStr = Regex.Replace(newStr, kvp.Key, kvp.Value, RegexOptions.IgnoreCase);
}
newCalcStr += newStr;
}
else
{
newCalcStr += str;
}
}
customField.Calculation = newCalcStr;
}

Исходный ввод
IIF([FIELD1] = "This ""quoted text inside string quotes"" and that" AnD [FIELD2] = "This or that", "Value 1",
iiF ([FIELD3] = "This and that" aNd [FIELD4] = "This or that", "Value 2",
IIF([FIELD4] = "This and that" Or [FIELD5] = "This or that", "Value 3",
Iif ([FIELD6] = "This and that" oR [FIELD7] = "This or that", "Value 4",
""))))

Вывод
IF([FIELD1] = "This ""quoted text inside string quotes"" and that" AndAlso [FIELD2] = "This or that", "Value 1",
IF([FIELD3] = "This and that" AndAlso [FIELD4] = "This or that", "Value 2",
IF([FIELD4] = "This and that" OrElse [FIELD5] = "This or that", "Value 3",
IF([FIELD6] = "This and that" OrElse [FIELD7] = "This or that", "Value 4",
""))))


Подробнее здесь: https://stackoverflow.com/questions/776 ... ing-quotes
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C#»