The following uses GNU 'sed' with basic regular expressions (as used by 'grep'), not extended regular expressions (as used by GNU 'sed -r' and 'egrep'). Your code seems to mix elements of both.
Code:
Your pattern
\((# )|(.\" )\)*
should be something like
\(# \|\.\\" \)\?
The literal brackets have been removed, then | . and \ escaped.
In GNU sed \? is the same as * but only matches zero or one times
\1 can be used to repeat the pattern on the left side of the s command.
There's no need to remove the \n created by the N command as it can be matched in the patterns.
The variables a,b,A,B,prefix are used here just to make the logic clearer.
Code:
a='Software Foundation; either version 2, or (at your option) any later'
b='version'
A='Software Foundation, either version 3 of the License, or (at your '
B='option) any later version'
prefix='# \|\.\\" '
sed '/Software Foundation/{
N
'"s/^\($prefix\)\?$a\n\1$b/\1$A\n\1$B/"'
}' file
# Software Foundation, either version 3 of the License, or (at your
# option) any later version
.\" Software Foundation, either version 3 of the License, or (at your
.\" option) any later version
Software Foundation, either version 3 of the License, or (at your
option) any later version