The Proteas triumphed with just three balls to spare after their target was twice adjusted due to stoppages but enough play was possible for both sides to show promise ahead of the upcoming tournament.
Tillakaratne Dilshan made a century as Sri Lanka posted 279-7 in 44.4 overs in a weather-curtailed innings and Quinton de Kock then tallied 66 for South Africa.
Sri Lanka were put in to bat and were 1-1 when opener Lahiru Thirimanne was caught behind by de Kock off Vernon Philander.
However, the experienced Dilshan made 100 off 83 balls, with 15 boundaries and a pair of sixes, and added 76 with Kumar Sangakkara (31) and 74 with Dimuth Karunaratne (46).
Dilshan was dismissed the ball after reaching his century but skipper Angelo Matthews hit 58 off 49 balls to keep the scoreboard ticking over nicely.
South Africa wanted to give plenty of bowlers a workout, using eight in total, with Kyle Abbott (3-37) and Wayne Parnell (2-42) faring best in terms of wickets taken.
South Africa captain AB de Villiers was rested due to tightness in a hip so Hashim Amla took charge of the side.
And Amla (46) and De Kock put on 116 for the first wicket, meaning South Africa were in a good position when rain intervened again.
JP Duminy (17), Faf du Plessis (19) and David Miller (4) departed as the South Africans closed in on victory, spinner Rangana Herath taking 3-22 for Sri Lanka.
But Rilee Rossouw (16 not out) and Vernon Philander (13 not out) kept their composure, Philander hitting a six as the penultimate over, bowled by Nuwan Kulasekara, went for 14, meaning just four runs were still required.
Expert one-day performer Lasith Malinga was back in the Sri Lanka side after a long absence with an ankle injury and he bowled the final over but the South Africans took four runs off the first three balls to secure victory.