This might be what you want:
\documentclass{article}
\usepackage{amsmath}
\usepackage[locale = DE]{siunitx}
\ExplSyntaxOn
\NewDocumentCommand\SIexpr{ m m }
{
\svend_siexpr:nn { #1 } { #2 }
}
\cs_new_protected:Npn \svend_siexpr:nn #1 #2
{
\seq_set_split:Nnn \l_svend_siexpr_input_seq { ; } { #1 }
\seq_pop_left:NN \l_svend_siexpr_input_seq \l_svend_siexpr_first_tl
\seq_clear:N \l_svend_siexpr_output_seq
\seq_put_right:Nx \l_svend_siexpr_output_seq
{
\fp_compare:nTF { \l_svend_siexpr_first_tl > 0 }
{ \num { \l_svend_siexpr_first_tl } }
{ - \num { \tl_tail:V \l_svend_siexpr_first_tl } }
}
\seq_map_inline:Nn \l_svend_siexpr_input_seq
{
\seq_put_right:Nx \l_svend_siexpr_output_seq
{
\fp_compare:nTF { ##1 > 0 }
{ + \num { ##1 } }
{ - \num { \tl_tail:n { ##1 } } }
}
}
\SI[parse-numbers=false]
{
\sisetup{parse-numbers}
( \seq_use:Nn \l_svend_siexpr_output_seq { } )
}
{ #2 }
}
\ExplSyntaxOff
\begin{document}
\begin{align*}
l
&= \SI{38.0}{\cm} + 2 \cdot \SI{26.2}{\cm} + \SI{32.6}{\cm}\\
&= \SIexpr{38.0; 52.4; 32.6}{\cm}\\
&= \SI{123.0}{\cm}.\\
l
&= \SI{38.0}{\cm} - 2 \cdot \SI{26.2}{\cm} + \SI{32.6}{\cm}\\
&= \SIexpr{38.0; -52.4; 32.6}{\cm}\\
&= \SI{18.2}{\cm}.\\
l
&= \SI{-38.0}{\cm} + 2 \cdot \SI{26.2}{\cm} + \SI{32.6}{\cm}\\
&= \SIexpr{-38.0; 52.4; 32.6}{\cm}\\
&= \SI{47.0}{\cm}.
\end{align*}
\end{document}

The argument to \SIexpr is split into components.
The first component is detached to be treated separately.
Each component is examined for seeing if it is positive or negative: if negative we add -\num{<absolute value>} else +\num{<absolute value>}.
However, a leading + is not added by doing a special examination to the first component.
To have the separator in the first mandatory argument to \SIexpr selectable with an optional argument, change the main code into
\ExplSyntaxOn
\NewDocumentCommand\SIexpr{ O{;} m m }
{
\svend_siexpr:nnn { #1 } { #2 } { #3 }
}
\cs_new_protected:Npn \svend_siexpr:nnn #1 #2 #3
{
\seq_set_split:Nnn \l_svend_siexpr_input_seq { #1 } { #2 }
\seq_pop_left:NN \l_svend_siexpr_input_seq \l_svend_siexpr_first_tl
\seq_clear:N \l_svend_siexpr_output_seq
\seq_put_right:Nx \l_svend_siexpr_output_seq
{
\fp_compare:nTF { \l_svend_siexpr_first_tl > 0 }
{ \num { \l_svend_siexpr_first_tl } }
{ - \num { \tl_tail:V \l_svend_siexpr_first_tl } }
}
\seq_map_inline:Nn \l_svend_siexpr_input_seq
{
\seq_put_right:Nx \l_svend_siexpr_output_seq
{
\fp_compare:nTF { ##1 > 0 }
{ + \num { ##1 } }
{ - \num { \tl_tail:n { ##1 } } }
}
}
\SI[parse-numbers=false]
{
\sisetup{parse-numbers}
( \seq_use:Nn \l_svend_siexpr_output_seq { } )
}
{ #3 }
}
\ExplSyntaxOff
Now you can do
\SIexpr{38.0; 52.4; 32.6}{\cm}
or
\SIexpr[,]{38.0, 52.4, 32.6}{\cm}
or even
\SIexpr[?]{38.0 ? 52.4 ? 32.6}{\cm}
If you prefer a comma by default, instead of a semicolon, you should have
\NewDocumentCommand\SIexpr{ O{,} m m }
The default separator can't be a colon, but you can select a colon with the optional argument.
\something{+}{38; -52.4; 32.6}{\cm}for example, and you don't want a+ -52.4in the output, then this can be done with other list processing methods, but don't know aboutsiunitx. – Peter Grill Oct 14 '14 at 21:00\SI[parse-numbers = false]{(38{,}0 - 52{,}4 + 32{,}6)}{\cm}. – Svend Tveskæg Oct 14 '14 at 21:37