@@ -1963,6 +1963,72 @@ extension RegexDSLTests {
19631963 XCTAssertEqual ( anyOutput [ 15 ] . value as? Int , 123 )
19641964 XCTAssertEqual ( anyOutput [ 16 ] . substring, " 456 " )
19651965 }
1966+
1967+ func testDeeplyNestedCapture( ) throws {
1968+ // Broken up: 'unable to type-check this expression in reasonable time'
1969+ let r0 = Optionally {
1970+ Capture {
1971+ OneOrMore ( CharacterClass . digit)
1972+ }
1973+ }
1974+ let r1 = ZeroOrMore {
1975+ Capture {
1976+ r0
1977+ }
1978+ }
1979+ let regex = Regex {
1980+ Capture {
1981+ OneOrMore {
1982+ Capture {
1983+ r1
1984+ }
1985+ }
1986+ }
1987+ }
1988+ XCTAssert ( type ( of: regex) . self
1989+ == Regex < ( Substring , Substring , Substring , Substring ? , Substring ? ? ) > . self)
1990+ let match = try XCTUnwrap ( " 123 " . wholeMatch ( of: regex) )
1991+ XCTAssertEqual ( match. output. 0 , " 123 " )
1992+ XCTAssertEqual ( match. output. 1 , " 123 " )
1993+ XCTAssertEqual ( match. output. 4 , " 123 " )
1994+ // Because capture groups only retain the last capture, these two groups
1995+ // are the empty string. After matching/capturing "123", the outer
1996+ // `OneOrMore` loops again, and since the innermost quanitifier is optional,
1997+ // the second loop matches the empty substring at the end of the input.
1998+ // That empty substring is then captured by capture groups 2 and 3.
1999+ XCTAssertEqual ( match. output. 2 , " " )
2000+ XCTAssertEqual ( match. output. 3 , " " )
2001+ }
2002+
2003+ func testVariedNesting( ) throws {
2004+ let regex = Regex {
2005+ " a "
2006+ OneOrMore {
2007+ Capture {
2008+ Optionally {
2009+ Capture {
2010+ " b "
2011+ }
2012+ }
2013+ " c "
2014+ }
2015+ " d "
2016+ }
2017+ " e "
2018+ ZeroOrMore {
2019+ Capture {
2020+ " f "
2021+ }
2022+ }
2023+ }
2024+ XCTAssert ( type ( of: regex) . self
2025+ == Regex< ( Substring, Substring, Substring? , Substring? ) > . self )
2026+ let match = try XCTUnwrap ( " acdbcdcde " . wholeMatch ( of: regex) )
2027+ XCTAssertEqual ( match. output. 0 , " acdbcdcde " )
2028+ XCTAssertEqual ( match. output. 1 , " c " )
2029+ XCTAssertEqual ( match. output. 2 , " b " )
2030+ XCTAssertNil ( match. output. 3 )
2031+ }
19662032}
19672033
19682034extension Unicode . Scalar {
0 commit comments