#c#
#c#
Вопрос:
Некоторые настройки хранятся в строке. Примером может быть
string rawWatermarkFormat = "{@Charge}; {Current Date} {Current Time}; Scan Operator: {Scan Operator's User ID}; Page: x/y";
Каждая подстрока, заключенная в {…}, представляет собой ключ для словаря. Этот словарь содержит значение, которое необходимо заменить ключом. Конечная строка будет
string parsedWatermarkFormat = "phosphoric acid; 24.04.2019 14:20; Scan Operator: 123; Page: x/y";
(да, текущая дата и текущее время также хранятся в этой коллекции)
Я хочу извлечь эти ключи, получить правильное значение из коллекции и заменить ключ значением. Я начал с этого
public Parse()
{
string watermarkFormat = "{@Charge}; {Current Date} {Current Time}; Scan Operator: {Scan Operator's User ID}; Page: x/y"; // batch.get_CustomStorageString(Resources.WATERMARK_FORMAT_KEY);
int currentFieldStart = 0;
for (int i = 0; i < watermarkFormat.Length; i )
{
char currentCharacter = watermarkFormat[i];
if (currentCharacter == '{')
{
currentFieldStart = i;
}
else if (currentCharacter == '}')
{
int length = i - currentFieldStart;
string currentField = watermarkFormat.Substring(currentFieldStart 1, length - 1);
string fieldValue = "---"; // access the collection for the correct field value
watermarkFormat = watermarkFormat
.Remove(currentFieldStart, length)
.Insert(currentFieldStart, fieldValue);
}
}
}
Проблема в том, что если бы я заменил подстроку с помощью диапазонов, строка оборвалась бы. Если ключ имеет длину x, а значение имеет длину y, метод replace не будет работать для следующих полей.
Таким образом, эта watermarkFormat
строка примера приведет к
---} {Current Time}; Scan Operator: ---}; Page: x/y
Как я могу правильно заменить поля?
Редактировать: rawWatermarkFormat
это всего лишь пример строки! Я не знаю его длины, токенов и т.д. Таким образом, строка может быть также такой
string rawWatermarkFormat = "{Current Date} {Current Date} {Current Date} {Current Date} {Current Date}"
или это
string rawWatermarkFormat = "{blue car}"
Я должен извлечь эти строки и получить правильное значение из словаря. Я сам не знаю эти токены.
Комментарии:
1. строки .net неизменяемы.
2. может помочь регулярное выражение.
3. почему цикл и все такое? Почему вы не можете использовать замену строки или формат строки или интерполяцию строки?
4. Я думаю, вы, возможно, ищете токенизацию строк для решения вашей основной бизнес-проблемы. github.com/flipbit/tokenizer
5. Я обновил свой ответ
Ответ №1:
Используйте регулярное выражение в качестве альтернативы.
string pattern = @"{[a-zA-Z-s@'] }";
string input = "{@Charge}; {Current Date} {Current Time}; Scan Operator: {Scan Operator's User ID}; Page: x/y";
var matches = System.Text.RegularExpressions.Regex.Matches(input, pattern);
foreach (var match in matches)
{
Console.WriteLine(match);
// TODO replace
// var key = match.ToString();
// input = input.Replace(key, someMethodToGetValue(key.Replace("{", "").Replace("}", "")));
}
Вывод на консоль:
{@Charge}
{Current Date}
{Current Time}
{Scan Operator's User ID}
Ответ №2:
Это можно довольно легко решить с Regex.Replace
помощью MatchEvaluator
перегрузки делегата.
Вот пример LINQPad:
void Main()
{
string rawWatermarkFormat = "{@Charge}; {Current Date} {Current Time}; Scan Operator: {Scan Operator's User ID}; Page: x/y";
Dictionary<string, string> keywordValues = new Dictionary<string, string>
{
["@Charge"] = "phosphoric acid",
["Current Date"] = "24.04.2019",
["Current Time"] = "14:20",
["Scan Operator's User ID"] = "123",
};
Regex.Replace(rawWatermarkFormat, @"{(?<keyword>[^}] )}", me =>
{
if (keywordValues.TryGetValue(me.Groups["keyword"].Value, out string value))
return value;
return me.Value;
}).Dump();
}
Это выводит:
phosphoric acid; 24.04.2019 14:20; Scan Operator: 123; Page: x/y
Комментарии:
1. Извините, но я не знаю токены во время выполнения, поэтому я не могу их настроить
2. Но у вас есть доступ к ним во время выполнения? Другими словами, если вы обнаружите, что одним из ключевых слов является
@Charge
, как бы вы нашли значение для его замены?3. Я не хотел сказать, что вы можете сделать это с помощью словаря, это был просто мой пример, внутри делегата вы можете написать любой код, который хотите получить, и вернуть значение для каждого ключевого слова.
4. коллекция (словарь) содержит это значение, а ключевое слово является просто ключом для этого словаря
5. То есть вы хотите сказать, что тогда мой код будет работать?
Ответ №3:
Это может сработать:
var Charge = "phosphoric acid";
var CurrentDate = "24.04.2019";
var CurrentTime = "14:20";
var ScanOperatorUserID = "123";
var interpolated = $"{Charge}; {CurrentDate} {CurrentTime}; Scan Operator: {ScanOperatorUserID}; Page: x/y";
string parsedWatermarkFormat = "phosphoric acid; 24.04.2019 14:20; Scan Operator: 123; Page: x/y";
Console.WriteLine(interpolated);
Console.WriteLine(parsedWatermarkFormat);
Console.ReadKey();
Надеюсь, это поможет.
Ответ №4:
Я делаю это наоборот. Получите словарь и замените любое упоминание ключа.
foreach(KeyValuePair<string,string> variable in variableDictionary )
{
fileContent = fileContent.Replace("$(" variable.Key ")", variable.Value);
}