Как заставить матч-реванш?
Я хотел бы принудительно провести матч-реванш в следующем сценарии - я пытаюсь выполнить обратное сопоставление квалификатора после каждого элемента в списке. Другими словами, у меня есть:
"int a, b, c" =~ m{
(?(DEFINE)
(?<qualifs>\s*(?<qualif>\bint\b|\bfloat\b)\s*+(?{print $+{qualif} . "\n"}))
(?<decl>\s*(?!(?&qualif))(?<ident>[_a-zA-Z][_a-zA-Z0-9]*+)\s*(?{print $+{ident} . "\n"}))
(?<qualifsfacet>\s*\bint\b\s*+)
(?<declfacet>[_a-zA-Z][_a-zA-Z0-9]*+)
)
^((?&qualifsfacet)*+(?!(?&decl))
|(?&qualifs)*+(?&declfacet)
|((?&qualifsfacet)
(?&declfacet)(?<negdecl>\g{lastnegdecl}(,(?&decl)))
|(?&qualifs)*+(?&declfacet)(?<lastnegdecl>\g{negdecl})
(?# Here how to force it to retry last with new lastnegdecl)))$
}xxs;
И хотел бы иметь:
a
int
b
int
c
int
Как вывод. Пока только это:
a
int
int
Я думаю, что это может сработать, если есть способ указать машине регулярных выражений повторно запустить совпадение для нового
lastnegdecl
что захватывается.
1 ответ
После некоторых попыток я наконец понял это (помимо очевидных проблем с пробелами, которые у меня были в моем исходном сообщении):
"int a, b, c" =~ m{
(?(DEFINE)
(?<qualifs>\s*+(?<qualif>\bint\b|\bfloat\b)\s*+(?{print $+{qualif} . "\n"}))
(?<decl>\s*+(?!(?&qualif))(?<ident>[_a-zA-Z][_a-zA-Z0-9]*+)\s*(?{print $+{ident} . "\n"}))
(?<qualifsfacet>\s*+(\bint\b|\bfloat\b)\s*+)
(?<declfacet>\s*+[_a-zA-Z][_a-zA-Z0-9]*+\s*+)
)
^((?&qualifsfacet)(?!(?&decl))
|(?&qualifs)*+(?&declfacet)
|(?<restoutter>(?=(?&qualifsfacet)(?&declfacet)
(?<rest>(?(<rest>)\g{rest}),(?&decl)))
((?&qualifs)(?&declfacet)\g{rest}|(?&restoutter)))
|(?&qualifsfacet)(?&declfacet)(,(?&declfacet))*+)$
}xxs;
В основном я делаю положительный прогноз, когда они вызываются с кодом, но не конкатенируются
decl
внутри, затем выполняя частичное совпадение с
qualifs
и
rest
и если он не совпадает, он снова делает то же самое. Может быть, кто-то сможет объяснить это лучше, но это работает. Результат вышеупомянутой программы:
a
int
b
int
c
int
И есть полное совпадение.