Durban - Marchant de Lange grabbed seven wickets on his South Africa debut but Thilan Samaraweera's century helped Sri Lanka total 338 in their first innings on the second day of the second test on Tuesday.
Fast bowler De Lange took seven for 81 as Sri Lanka were bowled out 35 minutes before lunch.
The 21-year-old's figures are the best by a South African against this opposition - surpassing Shaun Pollock's six for 30 in Cape Town in 2000-01.
Samaraweera scored 102 to steer Sri Lanka to their highest total in South Africa, beating the previous best of 323 at Centurion in 2002-03.
The 35-year-old's 13th test century was the second by a Sri Lankan in South Africa, after Hashan Tillekeratne's 104 not out in that Centurion test.
Captain Graeme Smith and Jacques Rudolph made a watchful start to the home team's reply, reaching 15 without loss in six overs before lunch.
De Lange's burst of three wickets in eight balls cut short Sri Lanka's resistance on the second morning after they had resumed on 289 for seven.
Samaraweera, who resumed on 86, continued to bat in a controlled fashion as he and Rangana Herath put on 46 for the eighth wicket.
De Lange then cleaned up the tail by removing Herath (30) and Chanaka Welegedara (2) with nasty, lifting deliveries.
Samaraweera was last man out, caught by deep cover Ashwell Prince off the young paceman.
South Africa lead the three-match series 1-0.