I think it’s useful here to look at the formal definition of regular expressions, i.e. look for every regular expression e that it expresses in the language of L (e).
So, let's just start:
(1) What about the regular expression a (letter only)? His tongue
L(a) := {a},
just one word / character "a".
(2) For the regular expression e1 + e2, where e1 and e2 are the regular expressions themselves,
L(e1 + e2) := L(e1) UL(e2).
So, for example, if a and b are symbols, L (a + b) = {a, b}.
(3) For the regular expression e1 e2 (concatenation), where e1 and e2 are the regular expressions themselves,
L(e1 e2) := all words w such that we can write w = w_1w_2 with w_1 in L(e1) and w_2 in L(e2)".
(4) What about the regular expression * e **, where e can be the regular expression itself? Intuitively, a word is in L (e *) if it has the form w_1 w_2w_3w_4 ... w_n, with w_i in L (e) for each i. So,
L(e*) := all words w such that we can write w = w_1 w_2 .. w_n for an >= 0 with all w_i in L(e) (for i = 1, 2, ..., n)
So, what about L ((a * + b *))?
L((a* + b*)) (according to rule 2) = L(a*) UL(b*) (according to rule 4/1) = {eps, a, aa, aaa, aaaa, ....} U {eps, b, bb, bbb, bbbb} = all strings that have either only a OR only b in it (including eps, the so-called empty word)
Similarly for (a * b *):
L((a* b*)) (according to rule 3) = all words w = w_1 w_2 with w_1 in L(a*) and w_2 in L(b*) = {eps eps, eps b, a eps, ab, aa eps, aab, ...} = {eps, b, a, ab, aa, aab, aabb, ... } = all strings that first have zero or more a's, then zero or more b's.
To begin with, I think this helps to “deconstruct” the regular expression, as we did above, since regular expressions can also be considered as trees, as well as the more well-known arithmetic expressions, for example:
+ / \ * * | | ab