0

我正在使用 Sprache 解析旧文件。

该文件具有以下结构,非常类似于键和值字典:

Entity
{
  propertyA simple
  propertyB 10-1
  propertyC "first"
  propertyD "I am a line that spawns
  to another line"
  propertyE "second"
  propertyF 1,2,3,4,5,6,\
    7,8,9,10,11,\
    12,13,14
  propertyG "one","two","three",\
  "four","five","six","seven",\
  "eight","nine"
}

我能够正确处理文件,但不能在它有“\”行继续时。

我所做的唯一肮脏的黑客攻击是替换作为输入发送到解析器的字符串并替换字符,因此没有行继续:

public static Document ParseLegsacyFile(string input)
{
     // HACK
     return Document.Parse(input.Replace("\\\r\n", string.Empty));
}

我不想承担这个技术债务...

无论如何指示解析器忽略模式“\”和“\r\n”并替换为空字符串?

我已经尝试过 except (with Or)、Return 和 Then ,但都没有成功。

这是我正在使用的解析器的一部分。以下仅用于“价值”部分:

      public static readonly Parser<GenericObject> Value =

        from value in Parse.AnyChar.Until(Parse.LineEnd).Text()

        select new GenericObject(value);



    private static readonly Parser<GenericString> SingleString =

        from result in (from open in Parse.Char(Quote)

            from content in Parse.CharExcept(Quote).Many().Text()

            from close in Parse.Char(Quote)

            select content).Token()

    select new GenericString(result);



   public static readonly Parser<GenericString> StringValue =

       from value in SingleString .DelimitedBy(Parse.Char(Char.Parse(Comma)))

       select new StringLiteral(string.Join(Comma, value));
4

1 回答 1

0

老问题,但答案可能对某人有所帮助:

您可以删除延续字符"\"并使用 Sprache 组合它们的行,如下所示:

            var text = @"...text here...";
            var result=  RemoveSlash(text).ToList();
           foreach (var l in result)
                Console.WriteLine(l);
        

        IEnumerable<string> RemoveSlash(string text)
        {
            // return;
            Parser<string> Eol = Parse.String("\\" + Environment.NewLine).Text();

            var oneLine = Parse.AnyChar.Until(Parse.LineEnd).Text();
            var multiLine =
                from l in Parse.AnyChar.Until(Eol).Text().Many()
                from c in oneLine.Once()
                let m = string.Join("", l.Concat(c))
                select m;

            var lines = multiLine.Or(oneLine);
            var result = lines.Many().Parse(text);
            return result;

        }

试试看

于 2021-12-10T16:04:20.733 回答