@@ -1963,6 +1963,72 @@ extension RegexDSLTests {
1963
1963
XCTAssertEqual ( anyOutput [ 15 ] . value as? Int , 123 )
1964
1964
XCTAssertEqual ( anyOutput [ 16 ] . substring, " 456 " )
1965
1965
}
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
+ }
1966
2032
}
1967
2033
1968
2034
extension Unicode . Scalar {
0 commit comments