首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Sprache解析器和字符转义

Sprache解析器和字符转义
EN

Stack Overflow用户
提问于 2015-09-29 04:38:43
回答 2查看 1.7K关注 0票数 3

我还没有找到一个例子--如何处理字符转义。我找到了一个代码示例:

代码语言:javascript
复制
static void Main(string[] args)
{
    string text = "'test \\\' text'";
    var result = Grammar.QuotedText.End().Parse(text);
}

public static class Grammar
{
    private static readonly Parser<char> QuoteEscape = Parse.Char('\\');
    private static Parser<T> Escaped<T>(Parser<T> following)
    {
        return from escape in QuoteEscape
               from f in following
               select f;
    }

    private static readonly Parser<char> QuotedTextDelimiter = Parse.Char('\'');

      private static readonly Parser<char> QuotedContent =
          Parse.AnyChar.Except(QuotedTextDelimiter).Or(Escaped(QuotedTextDelimiter));

    public static Parser<string> QuotedText = (
        from lquot in QuotedTextDelimiter
        from content in QuotedContent.Many().Text()
        from rquot in QuotedTextDelimiter
        select content
        ).Token();
}

如果文本不包含转义,它会成功解析文本,但不会解析字符转义的文本。

EN

回答 2

Stack Overflow用户

发布于 2015-11-02 00:47:45

我也遇到过类似的问题,使用"作为分隔符,\作为转义字符来解析字符串。我为此编写了一个简单的解析器(可能不是最优雅的解决方案),它似乎工作得很好。

您应该能够适应它,因为唯一的区别似乎是分隔符。

代码语言:javascript
复制
var escapedDelimiter = Parse.String("\\\"").Text().Named("Escaped delimiter");
var singleEscape = Parse.String("\\").Text().Named("Single escape character");
var doubleEscape = Parse.String("\\\\").Text().Named("Escaped escape character");
var delimiter = Parse.Char('"').Named("Delimiter");
var simpleLiteral = Parse.AnyChar.Except(singleEscape).Except(delimiter).Many().Text().Named("Literal without escape/delimiter character");

var stringLiteral = (from start in delimiter
            from v in escapedDelimiter.Or(doubleEscape).Or(singleEscape).Or(simpleLiteral).Many()
            from end in delimiter
            select string.Concat(start) + string.Concat(v) + string.Concat(end));

关键部分是from v in ...。它首先搜索转义分隔符,然后搜索双转义字符,然后搜索单个转义字符,然后尝试将其解析为不带任何转义或分隔符的"simpleLiteral“。更改这里的顺序将导致解析错误(例如,如果您试图在转义分隔符之前解析单个转义,您将永远找不到后者,对于双重转义和单个转义也是如此)。此步骤重复多次,直到出现未转义的分隔符(from v in ...不处理未转义的分隔符,但from end in delimiter当然处理)。

票数 6
EN

Stack Overflow用户

发布于 2021-12-06 08:50:30

我需要解析可以用单引号或双引号表示的字符串,而且还支持对这些字符串进行转义。

生成字符串文字解析器的方法:

代码语言:javascript
复制
private readonly StringBuilder _reusableStringBuilder = new StringBuilder();

private Parser<string> BuildStringLiteralParser(char delimiterChar)
{
    var escapeChar = '\\';

    var delimiter = Sprache.Parse.Char(delimiterChar);
    var escape = Sprache.Parse.Char(escapeChar);
    var escapedDelimiter = Sprache.Parse.String($"{escapeChar}{delimiterChar}");
    var splitByEscape = Sprache.Parse.AnyChar
        .Except(delimiter.Or(escape))
        .Many()
        .Text()
        .DelimitedBy(escapedDelimiter);

    string BuildStr(IEnumerable<IEnumerable<string>> splittedByEscape)
    {
        _reusableStringBuilder.Clear();

        var i = 0;

        foreach (var splittedByEscapedDelimiter in splittedByEscape)
        {
            if (i > 0)
            {
                _reusableStringBuilder.Append(escapeChar);
            }

            var j = 0;

            foreach (var str in splittedByEscapedDelimiter)
            {
                if (j > 0)
                {
                    _reusableStringBuilder.Append(delimiterChar);
                }

                _reusableStringBuilder.Append(str);

                j++;
            }

            i++;
        }

        return _reusableStringBuilder.ToString();
    }

    return (from ln in delimiter
            from splittedByEscape in splitByEscape.DelimitedBy(escape)
            from rn in delimiter
            select BuildStr(splittedByEscape)).Named("string");
}

用法:

代码语言:javascript
复制
var stringParser = BuildStringLiteralParser('\"').Or(BuildStringLiteralParser('\''));

var str1 = stringParser.Parse("\"'Hello' \\\"John\\\"\"");
Console.WriteLine(str1);

var str2 = stringParser.Parse("\'\\'Hello\\' \"John\"\'");
Console.WriteLine(str2);

输出:

代码语言:javascript
复制
'Hello' "John"
'Hello' "John"

查看正在运行的演示:https://dotnetfiddle.net/8wFNbj

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32831401

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档