South Africa beat Sri Lanka by five wickets with just three balls to spare in a thrilling rain-interrupted World Cup warm-up on Monday.

Sri Lanka smashed 279 for seven in their innings, which was reduced to 44.4 overs after rain stopped play at Hagley Oval in Christchurch.

Opener Tillakaratne Dilshan laid the foundations for a big Sri Lankan total when he belted exactly 100 off just 83 deliveries, which included 15 boundaries and two sixes.

He was well supported by the Sri Lankan captain Angelo Mathews, who made a quickfire 58 off 49 balls, and Dimuth Karunaratne, who chipped in with 46 off 61 deliveries.

Kyle Abbott was the pick of the South Africa bowlers, taking 3-37 while all-rounder Wayne Parnell bagged two wickets.

When the rain stopped and the South Africans started their reply, they were initially set 230 to win off 30 overs under the Duckworth-Lewis method.

Despite being without their captain AB de Villiers, who was rested as a precaution because of tightness in his hip, the Proteas made a flying start.

Quinton de Kock (66) and Hashim Amla (46) put on 115 for the opening wicket in 15 overs before the rain returned, forcing another delay.

South Africa's target was reduced to 188 off 25 overs, leaving them needing 72 of 10 overs with 10 wickets in hand.

What seemed like an easy chase suddenly began to look tricky when they lost de Kock and Amla in the first over after play resumed, then three more wickets before the end of the 23rd over.

Left-arm spinner Rangana Herath snatched three wickets for Sri Lanka, leaving South Africa requiring 21 off the last 14 balls, but Rilee Rossouw (16 not out) and Vernon Philander (13 not out) safely guided the Proteas to victory.

South Africa will play their final warm-up against New Zealand in Christchurch on Wednesday, while Sri Lanka will face Zimbabwe the same day.

The World Cup starts on Saturday when co-hosts New Zealand meet Sri Lanka in Christchurch and Australia play England in Melbourne.