Superpower: сопоставлять строку с парсером, только если она начинается строкой
Разбирая в супердержаве, как сопоставить строку, только если она является первой в строке?
Например, мне нужно сопоставить двоеточие A в "A: Hello Goodbye\n", но не в "Goodbye A: Hello\n"
3 ответа
Используя ваш пример здесь, я бы изменил ваш 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, так как я не уверен, почему в NodeParser
Я должен был поставить Try()
на первом парсере при сцеплении его с Or()
, но я бы добавил ошибку, если бы я ее не добавил.
Кроме того, ваша проверка при проверке input[1]
неверно (возможно, просто проблема с копированием-вставкой). Это должно быть проверка против "Goodbye A: Hello"
и не "Hello A: Goodbye"
Я действительно сделал нечто подобное, но я не использую токенизатор.
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) });
Я не проверял это, просто выписал это по памяти. Вышеуказанный парсер должен иметь следующее:
myClass.Key = "A:"
myClass.Value = " Hello Goodbye"
Если не RegexOptions.Multiline
установлено, ^
соответствует началу строки независимо от того, находится ли она в начале строки.
Вы можете, вероятно, использовать встроенный (?m)
включить мультилинию:
static TextParser<Unit> Actor { get; } =
from start in Span.Regex(@"(?m)^[A-Za-z][A-Za-z0-9_]+:")
select Unit.Value;