Использование имен перечислений в многострочной строке для связи каждой строковой строки с целочисленным значением перечисления.Есть ли способ лучше? - PullRequest
0 голосов
/ 02 марта 2019

Мой анализатор RTF должен обрабатывать два вида файлов rtf (по одному файлу на выполнение программы): файлы rtf, сохраненные из Word, и файлы rtf, созданные утилитой генератора отчетов COTS.RTF для каждого действителен, но отличается.Мой анализатор использует шаблоны регулярных выражений для обнаружения, извлечения и обработки различных элементов rtf в двух типах файлов rtf.

Я решил реализовать список шаблонов регулярных выражений rtf в двух словарях, один для шаблонов регулярных выражений rtf.необходим для файла rtf Word и другого для шаблонов регулярных выражений rtf, необходимого для файла rtf утилиты COTS.Во время выполнения мой синтаксический анализатор определяет, какой тип файла RTF обрабатывается (Word RTF включает в себя элемент RTF //schemas.microsoft.com/office/word, а COTS RTF - нет), а затем получает необходимый шаблон регулярных выражений из подходящего словаря.

Чтобы облегчить задачу ссылки на шаблоны при написании кода, я реализовал перечисление, где каждое значение перечисления представляет определенный шаблон регулярного выражения.Чтобы облегчить задачу синхронизации шаблонов с их соответствующими перечислениями, я реализовал шаблоны регулярных выражений в виде here-string, где каждая строка представляет собой композицию csv: {enum name}, {word rtf regex pattern}, {cots rtf regex pattern}.Затем, во время выполнения, когда шаблоны загружаются в их словари, я получаю значение int для enum из csv и использую его для создания ключа словаря.

Это облегчает написание кода, но я 'Я не уверен, что это лучший способ для реализации и ссылки на выражения RTF.Есть ли способ лучше?

Пример кода:

public enum Rex {FOO, BAR};

string ex = @"FOO, word rtf regex pattern for FOO, cots rtf regex pattern for FOO
BAR, word rtf regex pattern for BAR, cots rtf regex pattern for BAR
";  

Я загружаю словари так:

using (StringReader reader = new StringReader(ex))
{
    string line;

    while ((line = reader.ReadLine()) != null)
    {
        string[] splitLine = line.Split(',');
        int enumIntValue = (int)(Rex)Enum.Parse(typeof(Rex), splitLine[0].Trim());
        ObjWordRtfDict.Add(enumIntValue, line.Split(',')[1].Trim());
        ObjRtfDict.Add(enumIntValue, line.Split(',')[2].Trim());
    }
}

Затем во время выполнения я получаю доступ к ObjWordRtfDict или ObjRtfDict в зависимости от типа rtf.файл, который анализатор обнаруживает.

string regExPattFoo = ObjRegExExpr.GetRegExPattern(ClsRegExExpr.Rex.FOO);

public string GetRegExPattern(Rex patternIndex)
{
    string regExPattern = "";

    if (isWordRtf)
    {
        ObjWordRtfDict.TryGetValue((int)patternIndex, out regExPattern);
    }
    else
    {
        ObjRtfDict.TryGetValue((int)patternIndex, out regExPattern);
    }

    return regExPattern;
}

Модифицированный Новый код, основанный на рекомендациях Асифа

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

Пример CSV-файла, включенного в качестве встроенного ресурса

SECT,^\\pard.*\{\\rtlch.*\\sect\s\}, ^\\pard.*\\sect\s\}
HORZ_LINE2, \{\\pict.*\\pngblip, TBD

Пример использования

string sectPattern = ObjRegExExpr.GetRegExPattern(ClsRegExPatterns.Names.SECT);

Класс ClsRegExPatterns

using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;

namespace foo
{
    public class ClsRegExPatterns
    {
        readonly bool isWordRtf = false;
        List<ClsPattern> objPatternList;

        public enum Names { SECT, HORZ_LINE2 };

        public class ClsPattern
        {
            public string Name { get; set; }
            public string WordRtfRegex { get; set; }
            public string COTSRtfRegex { get; set; }
        }

        public ClsRegExPatterns(StringBuilder rawRtfTextFromFile)
        {
            // determine if input file is Word rtf or not Word rtf
            if ((Regex.Matches(rawRtfTextFromFile.ToString(), "//schemas.microsoft.com/office/word", RegexOptions.IgnoreCase)).Count == 1)
            {
                isWordRtf = true;
            }

            //read patterns from embedded content csv file
            string patternsAsCsv = new StreamReader((Assembly.GetExecutingAssembly()).GetManifestResourceStream("eLabBannerLineTool.Packages.patterns.csv")).ReadToEnd();

            //create list to hold patterns
            objPatternList = new List<ClsPattern>();

            //load pattern list
            using (StringReader reader = new StringReader(patternsAsCsv))
            {
                string line;

                while ((line = reader.ReadLine()) != null)
                {
                    string[] splitLine = line.Split(',');

                    ClsPattern objPattern = new ClsPattern
                    {
                        Name = splitLine[0].Trim(),
                        WordRtfRegex = splitLine[1].Trim(),
                        COTSRtfRegex = splitLine[2].Trim()
                    };

                    objPatternList.Add(objPattern);
                }
            }
        }

        public string GetRegExPattern(Names patternIndex)
        {
            string regExPattern = "";

            string patternName = patternIndex.ToString();

            if (isWordRtf)
            {
                regExPattern = objPatternList.SingleOrDefault(x => x.Name == patternName)?.WordRtfRegex;
            }
            else
            {
                regExPattern = objPatternList.SingleOrDefault(x => x.Name == patternName)?.COTSRtfRegex;
            }

            return regExPattern;
        }
    }
}

1 Ответ

0 голосов
/ 03 марта 2019

Если я правильно понимаю формулировку вашей проблемы;Я бы предпочел что-то вроде ниже.

Создайте класс с именем RtfProcessor

 public class RtfProcessor
        {
            public string Name { get; set; }
            public string WordRtfRegex { get; set; }
            public string COTSRtfRegex { get; set; }

            void ProcessFile()
            {
                throw new NotImplementedException();
            }

        }

Где имя означает FOO или BAR и т. Д. Вы можете вести список таких файлов и продолжать заполнять их из CSV-файлов.как показано ниже

List<RtfProcessor> fileProcessors = new List<RtfProcessor>();
            using (StringReader reader = new StringReader(ex))
            {
                string line;

                while ((line = reader.ReadLine()) != null)
                {
                    string[] splitLine = line.Split(',');
                    RtfProcessor rtfProcessor = new RtfProcessor();
                    rtfProcessor.Name = splitLine[0].Trim();
                    rtfProcessor.WordRtfRegex = line.Split(',')[1].Trim();
                    rtfProcessor.WordRtfRegex = line.Split(',')[2].Trim();
                    fileProcessors.Add(rtfProcessor);
                }
            }

И получить шаблон регулярного выражения для FOO или BAR

 // to get the regex parrtern for FOO you can use
  fileProcessors.SingleOrDefault(x => x.Name == "FOO")?.WordRtfRegex;

надеюсь, это поможет.

...