#c#
Вопрос:
У меня есть строковое значение:
Пример:
string msg = "array('B', [255, 216, 255, 224, 0, 16, 74, 70, 73, 70, 0, 1, 1, 0, 0,
1, 0, 1, 0, 0, 255, 219, 0, 67, 0, 2, 1, 1, 1, 1, 1, 2, 1, 1, 1, 2, 2,
2, 2, 2, 4, 3, 2, 2, 2, 2, 5, 4, 4, 3, 4, 6, 5, 6, 6, 6, 5, 6, 6, 6,
7, 9, 8, 6, 7, 9, 7, 6, 6, 8, 11, 8, 9, 10, 10, 10, 10, 10, 6, 8, 11,
12, 11, 10, 12, 9, 10, 10, 10, 255, 219, 0, 67, 1, 2, 2, 2, 2, 2, 2,
5, 3, 3, 5, 10, 7, 6, 7, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10])"
Я хочу преобразовать это строковое значение в тип byte[].
private byte[] data;
//after type conversion from string to byte array
Debug.Log("data in byte array is: " data);
Результат должен быть:
данные в массиве байтов являются: [255, 216, 255, 224, 0, 16, 74, 70, 73, 70, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 255, 219, 0, 67, 0, 2, 1, 1, 1, 1, 1, 2, 1, 1, 1, 2, 2, 2, 2, 2, 4, 3, 2, 2, 2, 2, 5, 4, 4, 3, 4, 6, 5, 6, 6, 6, 5, 6, 6, 6, 7, 9, 8, 6, 7, 9, 7, 6, 6, 8, 11, 8, 9, 10, 10, 10, 10, 10, 6, 8, 11, 12, 11, 10, 12, 9, 10, 10, 10, 255, 219, 0, 67, 1, 2, 2, 2, 2, 2, 2, 5, 3, 3, 5, 10, 7, 6, 7, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10]
Поскольку фактическая строка msg имеет очень большое значение, я хочу сделать это с минимальным возможным временем выполнения.
Комментарии:
1. Можете ли вы уточнить
string msg =
, действительно ли это часть строки? Я предполагаю, что это так, поскольку вы включили его в блок цитат.2. Ваш первый пример не является допустимым C# (как и второй на самом деле), и в лучшем случае неоднозначен, также я помню, что на днях мне задали что-то вроде этого вопроса
3. дело в том, что вы хотите «минимально возможное время выполнения».??
4. Не уверен в минимальном времени выполнения. Самый простой способ-сопоставить
[(d{1,3}(?:,d{1,3})*)]
, разделить группу 1, а затем вызватьbyte.Parse()
элементы. Возможно, вам захочется использовать что-то более строгое, чемd
гарантия диапазона 0-255.5. @Llama
string msg =
не является частью строки. извините, я удалил блок цитат.
Ответ №1:
Похоже на довольно простую проблему синтаксического анализа. Мы могли бы запустить полный синтаксический анализатор для этого формата, но это, вероятно, выходит далеко за рамки ваших потребностей.
Давайте вместо этого предположим, что ваш msg
файл всегда будет в указанном формате , начиная с "array('B', ["
, заканчивая "])"
и имея 0 или более десятичных значений, разделенных запятыми. Поскольку любой выбранный вами вариант будет сканировать строку по крайней мере один раз, мы можем разработать код, чтобы сделать именно это.
Фактическое содержимое содержит только 4 типа символов:
- цифра (
0
—9
) - запятая (
,
) - пространство (
- конечный массив (
]
)
Мы можем перебирать символы, начиная с первого символа после начального массива ( [
со смещением 11), и что-то делать с каждым из этих типов символов: игнорировать его, обновлять текущее значение, возвращать текущее значение и/или выходить.
Если все предположения верны, то это простой процесс. Одно сканирование символов, никаких выделений в самом анализаторе. Вот образец:
IEnumerable<byte> ParseArrayMsg(string msg)
{
if (!msg.StartsWith("array('B', [") || !msg.EndsWith("])"))
yield break;
int value = 0;
for (int i = msg.IndexOf('[') 1; i < msg.Length; i )
{
var c = msg[i];
if (c == ',' || c == ']')
{
yield return (byte)value;
value = 0;
if (c == ']')
break;
}
else if (char.IsDigit(c))
value = value * 10 (int)(c - '0');
else if (c != ' ')
throw new Exception($"Invalid character '{c}' at index '{i}'.");
}
}
Возвращенный перечисляемый объект затем может быть обработан так, как вам нравится.
Ваш код на самом деле не будет выдавать желаемый результат, но это будет:
var data = ParseArrayMsg(msg).ToArray();
Console.WriteLine($"Data in byte array is: [{string.Join(", ", data.Select(b => b.ToString()))}]");
Данные в байтовый массив: [255, 216, 255, 224, 0, 16, 74, 70, 73, 70, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 255, 219, 0, 67, 0, 2, 1, 1, 1, 1, 1, 2, 1, 1, 1, 2, 2, 2, 2, 2, 4, 3, 2, 2, 2, 2, 5, 4, 4, 3, 4, 6, 5, 6, 6, 6, 5, 6, 6, 6, 7, 9, 8, 6, 7, 9, 7, 6, 6, 8, 11, 8, 9, 10, 10, 10, 10, 10, 6, 8, 11, 12, 11, 10, 12, 9, 10, 10, 10, 255, 219, 0, 67, 1, 2, 2, 2, 2, 2, 2, 5, 3, 3, 5, 10, 7, 6, 7, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10]
Ответ №2:
Вы можете попробовать сделать следующее:
string yourString= "Your String";
// Convert a C# string to a byte array
byte[] bytes = Encoding.ASCII.GetBytes(yourString);