diff --git a/RegExtract.Test/Usage.cs b/RegExtract.Test/Usage.cs index b8c1f40..5213ea7 100644 --- a/RegExtract.Test/Usage.cs +++ b/RegExtract.Test/Usage.cs @@ -132,6 +132,16 @@ public void a010() Assert.Equal([[['a', 's', 'd', 'f'], ['l', 'k', 'j']], [['w', 'e', 'r', 'o'], ['o', 'i', 'u']]], result); } + [Fact] + public void a011() + { + var plan = CreateAndLogPlan<((char? type, string name) module, List outputs)>(/* language=regex */@"^(([%&])?([a-z]+)) -> (([a-z]+),? ?)+$"); + + var result = plan.Extract("&kx -> zs, br, jd, bj, vg"); + + Assert.Equivalent((('&', "kx"), new List() { "zs", "br", "jd", "bj", "vg"}), result); + } + [Fact] public void slow() { diff --git a/RegExtract/ExtractionPlan.cs b/RegExtract/ExtractionPlan.cs index 78b5090..c4153d7 100644 --- a/RegExtract/ExtractionPlan.cs +++ b/RegExtract/ExtractionPlan.cs @@ -226,10 +226,12 @@ private ExtractionPlanNode AssignTypesToTree(RegexCaptureGroupNode tree, Type ty if (IsDirectlyConstructable(type)) { + // We're at a leaf--if there's an inner capture group, use it instead of everything. if (tree.children.Count() == 1) { - return new VirtualUnaryTupleNode(tree.name, type, new[] { AssignTypesToTree(tree.children.Single(), type) }, new ExtractionPlanNode[0]); + tree = tree.children.Single(); } + return ExtractionPlanNode.BindLeaf(tree.name, type, groups.ToArray(), namedgroups.ToArray()); } else if (IsTuple(unwrappedType))