C # как найти и заменить конкретный текст в строке? - PullRequest
0 голосов
/ 25 сентября 2018

У меня есть string, который представляет байтовый массив , внутри него у меня есть несколько групп чисел (обычно 5): которые кодируются как 0x30..0x39 (коды для 0..9 цифр). До и после каждого числа у меня есть пробел (0x20 код).

Примеры:

"E5-20-32-36-20-E0"                // "32-36" encodes number "26", notice spaces: "20"
"E5-20-37-20-E9"                   // "37" encodes number "7"
"E5-20-38-20-E7-E4-20-37-35-20-E9" // two numbers: "8" (from "38") and "75" (from "37-35")

Я хочу выяснить все эти группы и обратные цифры в кодированных числах :

   8 -> 8
  75 -> 57
 123 -> 321

Желаемый результат:

"E5-20-32-36-20-E0"                   -> "E5-20-36-32-20-E0"
"E5-20-37-20-E9"                      -> "E5-20-37-20-E9"
"E5-20-37-38-39-20-E9"                -> "E5-20-39-38-37-20-E9" 
"E5-20-38-39-20-E7-E4-20-37-35-20-E9" -> "E5-20-39-38-20-E7-E4-20-35-37-20-E9"

У меня есть данные внутри List \ String \ Byte[] - так что, возможно, есть способ сделать это?

Спасибо,

Ответы [ 3 ]

0 голосов
/ 25 сентября 2018

Если вам будет понятно, как вы хотите обрабатывать числа, вам будет проще найти решение.

  • Хотите ли вы поменять их случайным образом?
  • Хотите ли вы изменить порядок?
  • Хотите ли вы поменять местами каждое второе число с предыдущим?1008 *
  • Хотите поменяться местами ...

Вы можете попробовать следующее (для изменения чисел)

string hex = "E5-20-36-32-20-E0"; // this is your input string

// split the numbers by '-' and generate list out of it
List<string> hexNumbers = new List<string>();
hexNumbers.AddRange(hex.Split('-'));

// find start and end of the numbers that should be swapped
int startIndex = hexNumbers.IndexOf("20");
int endIndex = hexNumbers.LastIndexOf("20");

string newHex = "";
// add the part in front of the numbers that should be reversed
for (int i = 0; i <= startIndex; i++) newHex += hexNumbers[i] + "-";
// reverse the numbers
for (int i = endIndex-1; i > startIndex; i--) newHex += hexNumbers[i] + "-";
// add the part behind the numbers that should be reversed
for (int i = endIndex; i < hexNumbers.Count-1; i++) newHex += hexNumbers[i] + "-";
newHex += hexNumbers.Last();

Если начало и конец всегдато же самое, это может быть довольно упрощено в 4 строки кода:

string[] hexNumbers = hex.Split('-');
string newHex = "E5-20-";
for (int i = hexNumbers.Count() - 3; i > 1; i--) newHex += hexNumbers[i] + "-";
newHex += "20-E0";

Результаты:

"E5-20-36-32-20-E0" -> "E5-20-32-36-20-E0"
"E5-20-36-32-37-20-E0"    -> "E5-20-32-37-36-20-E0"
"E5-20-36-12-18-32-20-E0" -> "E5-20-32-18-12-36-20-E0"
0 голосов
/ 25 сентября 2018

Непонятно (из оригинального вопроса), что вы хотите делать с цифрами;давайте извлечем пользовательский метод для его реализации.Например, я реализовал reverse :

32          -> 32
32-36       -> 36-32
36-32-37    -> 37-32-36
36-37-38-39 -> 39-38-37-36

Код:

// items: array of digits codes, e.g. {"36", "32", "37"}
//TODO: put desired transformation here
private static IEnumerable<string> Transform(string[] items) {
  // Either terse Linq:
  // return items.Reverse();

  // Or good old for loop:
  string[] result = new string[items.Length];

  for (int i = 0; i < items.Length; ++i)
    result[i] = items[items.Length - i - 1];

  return result;
}

Теперь мы можем использовать регулярные выражения (Regex), чтобы извлечь все последовательности цифр и заменить их на преобразованные:

  using System.Text.RegularExpressions;

  ...

  string input = "E5-20-36-32-37-20-E0";

  string result = Regex
    .Replace(input, 
           @"(?<=20\-)3[0-9](\-3[0-9])*(?=\-20)", 
             match => string.Join("-", Transform(match.Value.Split('-'))));

  Console.Write($"Before: {input}{Environment.NewLine}After:  {result}";);

Результат:

Before: E5-20-36-32-37-20-E0
After:  E5-20-37-32-36-20-E0

Редактировать: В случае перевернуть - единственное желаемое преобразование, код можно упростить, опустив Transform и добавив Linq :

using System.Linq;
using System.Text.RegularExpressions;

...

string input = "E5-20-36-32-37-20-E0";

string result = Regex
  .Replace(input, 
          @"(?<=20\-)3[0-9](\-3[0-9])*(?=\-20)", 
           match => string.Join("-", match.Value.Split('-').Reverse()));

Дополнительные тесты:

private static string MySolution(string input) {
  return Regex
    .Replace(input,
           @"(?<=20\-)3[0-9](\-3[0-9])*(?=\-20)",
             match => string.Join("-", Transform(match.Value.Split('-'))));
} 

...

string[] tests = new string[] {
  "E5-20-32-36-20-E0",
  "E5-20-37-20-E9",
  "E5-20-37-38-39-20-E9",
  "E5-20-38-39-20-E7-E4-20-37-35-20-E9",
};

string report = string.Join(Environment.NewLine, tests
  .Select(test => $"{test,-37} -> {MySolution(test)}"));

Console.Write(report);

Результат:

E5-20-32-36-20-E0                     -> E5-20-36-32-20-E0
E5-20-37-20-E9                        -> E5-20-37-20-E9
E5-20-37-38-39-20-E9                  -> E5-20-39-38-37-20-E9
E5-20-38-39-20-E7-E4-20-37-35-20-E9   -> E5-20-39-38-20-E7-E4-20-35-37-20-E9

Изменить 2: Объяснение регулярного выражения (подробности см. https://www.regular -expressions.info / lookaround.html ):

   (?<=20\-)         - must appear before the match: "20-" ("-" escaped with "\")
   3[0-9](\-3[0-9])* - match itself (what we are replacing in Regex.Replace) 
   (?=\-20)          - must appear after the match "-20" ("-" escaped with "\")

Давайте посмотрим на часть матча 3[0-9](\-3[0-9])*:

   3           - just "3"
   [0-9]       - character (digit) within 0-9 range
   (\-3[0-9])* - followed by zero or more - "*" - groups of "-3[0-9]"
0 голосов
/ 25 сентября 2018

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

  • Поместите строку в 2 массива (чтобы они были одинаковыми)
  • Переберите один из них, чтобы найти начало и конец области чисел
  • Переход от конечной области к начальной области в первом массиве и запись во второй из начальной области к конечной области

Редактировать: не проверено, я просто написал это быстро:

    string input = "E5-20-36-32-37-20-E0";
    string[] array1 = input.Split('-');
    string[] array2 = input.Split('-');

    int startIndex = -1;
    int endIndex = -1;

    for (int i= 0; i < array1.Length; ++i)
    {
        if (array1[i] == "20")
        {
            if (startIndex < 0)
            {
                startIndex = i + 1;
            }
            else
            {
                endIndex = i - 1;
            }
        }
    }

    int pos1 = startIndex;
    int pos2 = endIndex;
    for (int j=0; j < (endIndex- startIndex + 1); ++j)
    {
        array1[pos1] = array2[pos2];
        pos1++;
        pos2--;
    }
...