C# 超级能力:仅当字符串以一行开头时才与解析器匹配

C# 超级能力:仅当字符串以一行开头时才与解析器匹配,c#,tokenize,superpower,C#,Tokenize,Superpower,在superpower中解析时,如何仅在字符串是行中的第一项时匹配它 例如,我需要在A:Hello再见中匹配冒号A,但在再见A:Hello\n中不匹配冒号A,除非设置了RegexOptions.Multiline,^匹配字符串的开头,而不管它是否在行的开头 您可能可以使用inline?m启用多行: static TextParser<Unit> Actor { get; } = from start in Span.Regex(@"(?m)^[A-Za-z][A-Za-z0-9_

在superpower中解析时,如何仅在字符串是行中的第一项时匹配它

例如,我需要在A:Hello再见中匹配冒号A,但在再见A:Hello\n中不匹配冒号A,除非设置了RegexOptions.Multiline,^匹配字符串的开头,而不管它是否在行的开头

您可能可以使用inline?m启用多行:

static TextParser<Unit> Actor { get; } =
  from start in Span.Regex(@"(?m)^[A-Za-z][A-Za-z0-9_]+:")
  select Unit.Value;
使用您的示例,我将您的ActorParser和NodeParser定义更改为:

public readonly static TokenListParser<Tokens, Node> ActorParser =
    from name in NameParser
    from colon in Token.EqualTo(Tokens.Colon)
    from text in TextParser
    select new Node {
        Actor = name + colon.ToStringValue(),
        Text = text
    };

public readonly static TokenListParser<Tokens, Node> NodeParser =
    from node in ActorParser.Try()
        .Or(TextParser.Select(text => new Node { Text = text }))
    select node;
我觉得Superpower有一个bug,因为我不知道为什么在NodeParser中,我必须在第一个解析器上尝试使用Or链接,但是如果我不添加它,它会抛出一个错误


此外,检查输入[1]时的验证不正确,可能只是复制粘贴问题。它应该检查再见A:你好,而不是你好A:再见

我实际上做了类似的事情,但我没有使用标记器

private static string _keyPlaceholder;

private static TextParser<MyClass> Actor { get; } =
    Span.Regex("^[A-Za-z][A-Za-z0-9_]*:")
        .Then(x =>
             {
                 _keyPlaceholder = x.ToStringValue();
                 return Character.AnyChar.Many();
             }
         ))
    .Select(value => new MyClass { Key = _keyPlaceholder, Value = new string(value) });

传递RegexOptions.Multiline选项并不能解决问题:Span.Regex@^[A-Za-z][A-Za-z0-9_3;]*:,RegexOptions.multilehmmm-如果Multiline不能解决问题,那么您收到的跨度很可能是一个与您认为的不同的切片,而不是一条线对应的切片。尝试破解代码并检查跨度。如果这不能解决您的问题,那么发布一个演示失败的最小工作示例,这样我们就可以运行它并帮助您解决问题。好的,如果行为1 abc:并且设置了IgnoreSpan.WhiteSpace,那么标记器将使用第一个标记“1”,然后按照指示忽略空白,然后将abc:视为从位置0开始,因此匹配。但我只想匹配abc:如果它是第一个标记。。。如何做到这一点?您不能从标记器内部做到这一点,因为它只会在处理完之前的标记后看到剩余的标记。如果你在更高的层次上解释更多你想要做的事情,举例说明你期望的全部输入和你想要完成的确切行为,可能会有所帮助。标记化行为根据规则将输入分解为多个标记;如果你想选择一个特定的标记,你会在标记器完成后这样做。你能发布一个编译和执行的最小演示程序来展示你正在描述的行为吗?你是否试图解析多行文本,比如:你好,再见?你的预期产出是多少?键/值对,例如Key=A和value=Hello再见?另外,您是否希望再见A:Hello解析失败?我想这取决于它是标记器还是解析器。如果标记器是我认为更好的解决方案,那么我希望任何与上述正则表达式匹配的东西都是标记。这实际上取决于您的预期输出。您试图从中提取哪些数据?通过上下文的方式,语言中的每个命令都是以换行符结尾的单行,某些字符/字符串如果开始换行,则具有特殊意义,但如果它们在以后出现,则不具有特殊意义。因此,如果它发生在解析器中,那么它可能会返回一个Actor对象,其中包含字符串A:,然后是一个FreeText对象,其中包含字符串Hello-bye。在第二种情况下,整个事情将是freetext再见A:您好,因为Actor解析器将失败。我想我理解,但是要构建这样的解析器,您需要提供一个更全面的示例。你能更新这个问题,把它和你想把输出解析成的类一起包括进去吗?谢谢你的更新。我接受这一点,尽管我意识到我真正需要的是标记器版本,它与测试用例一起提供。。。
myClass.Key = "A:"
myClass.Value = " Hello Goodbye"