It's easier using a tool that supports lookarounds:
$ s="battery.charge: 90 battery.charge.low: 30 battery.runtime: 3690 battery.voltage: 230.0 device.mfr: MGE UPS SYSTEMS device.model: Pulsar Evolution 500"
$ grep -oP '\S+:\s+.*?(?=\s+\S+:|$)' <<< "$s"
battery.charge: 90
battery.charge.low: 30
battery.runtime: 3690
battery.voltage: 230.0
device.mfr: MGE UPS SYSTEMS
device.model: Pulsar Evolution 500
If you wanted the result in an array:
$ IFS=$'\n' foo=($(grep -oP '\S+:\s+.*?(?=\s+\S+:|$)' <<< "$s"))
$ for i in "${!foo[@]}"; do echo "$i<==>${foo[i]}"; done
0<==>battery.charge: 90
1<==>battery.charge.low: 30
2<==>battery.runtime: 3690
3<==>battery.voltage: 230.0
4<==>device.mfr: MGE UPS SYSTEMS
5<==>device.model: Pulsar Evolution 500
EDIT: Explanation of the regex:
'\S+:\s+.*?(?=\s+\S+:|$)'
\S+matches one or more non-whitespace characters:matches:\s+matches one or more spaces after the:.*?denotes a non-greedy match(?=\s+\S+:|$)is a lookahead assertion to determine if there is:- one or more space followed by a string (non-whitespace charaters) and a colon, or
- end of string
So the string is split into parts like battery.charge: 90, ... device.mfr: MGE UPS SYSTEMS, ...
Below are links to a couple of online regular expression analyzers: