Как выполнить несколько последовательных замен Regex из списка уникальных элементов чисто в C # - PullRequest
0 голосов
/ 20 октября 2019

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

Например, если у меня есть 3 пары замен шаблоновстроки:

1. /(?<!\\)\\n/, "\n"

2. /(\\)(?=[\;\:\,])/, ""

3. /(\\{2})/, "\\"

Я хочу применить замену регулярного выражения 1 к исходной строке, а затем применить 2на выходе 1 и т. д. и т. п.

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

SanitizeString

static public string SanitizeString(string param)
{
    string retval = param;
    //first replacement
    Regex SanitizePattern = new Regex(@"([\\\;\:\,])");
    retval = SanitizePattern.Replace(retval, @"\$1");

    //second replacement
    SanitizePattern = new Regex(@"\r\n?|\n");
    retval = SanitizePattern.Replace(retval, @"\n");

    return retval;
}

ParseCommands

static public string ParseCommands(string param)
{
    string retval = param;
    //first replacement
    Regex SanitizePattern = new Regex(@"(?<!\\)\\n");
    retval = SanitizePattern.Replace(retval, System.Environment.NewLine);

    //second replacement
    SanitizePattern = new Regex(@"(\\)(?=[\;\:\,])");
    retval = SanitizePattern.Replace(retval, "");

    //third replacement
    SanitizePattern = new Regex(@"(\\{2})");
    retval = SanitizePattern.Replace(retval, @"\");

    return retval;
}

Main

using System;
using System.IO;
using System.Text.RegularExpressions;

...

static void Main(string[] args)
{
    //read text that contains user input
    string sampleText = File.ReadAllText(@"c:\sample.txt");

    //sanitize input with certain rules
    sampleText = SanitizeString(sampleText);
    File.WriteAllText(@"c:\sanitized.txt", sampleText);

    //parses escaped characters back into the original text
    sampleText = ParseCommands(sampleText);
    File.WriteAllText(@"c:\parsed_back.txt", sampleText);
}

Не обращайте внимания на файловые операции. Я просто использовал это как быстрый способ визуализации фактического результата. В моей программе я собираюсь использовать что-то другое.

1 Ответ

1 голос
/ 20 октября 2019

Вот один из способов:

var replacements = new List<(Regex regex, string replacement)>()
{
    (new Regex(@"(?<!\\)\\n"), System.Environment.NewLine),
    (new Regex(@"(\\)(?=[\;\:\,])"), ""),
    (new Regex(@"(\\{2})"), @"\"),
};

(в идеале кэшировать это в статическом поле только для чтения):

Тогда:

string retval = param;
foreach (var (regex, replacement) in replacements)
{
    retval = regex.Replace(retval, replacement);
}

Или вы можете пойти внизЛинк маршрут:

string retval = replacements
    .Aggregate(param, (str, x) => x.regex.Replace(str, x.replacement));
...