3番目の数字グループは正規表現で必須です。
^something/(?P<id1>\d+)/(?P<id2>\d+)/(?:(?P<id3>\d+)/)?(?:(?P<id4>\d+)/)?$
また、書かれているように、3番目と4番目のグループの後のスラッシュは必須です。
In [4]: p = re.compile(r'^something/(?P<id1>\d+)/(?P<id2>\d+)/(?:(?P<id3>\d+)/)?(?:(?P<id4>\d+)/)?$')
In [5]: p.match('something/1/2/3/4/').groups()
Out[5]: ('1', '2', '3', '4')
In [6]: p.match('something/1/2/3/4').groups()
Out[6]: ('1', '2', '3', None)
In [7]: p.match('something/1/2/3/').groups()
Out[7]: ('1', '2', '3', None)
In [8]: p.match('something/1/2/3').groups()
Out[8]: ('1', '2', None, None)
In [9]: p.match('something/1/2/').groups()
Out[9]: ('1', '2', None, None)
3番目のグループを4番目のグループに移動し、4番目のグループをオプションにすることができます。
In [12]: p = re.compile(r'^something/(?P<id1>\d+)/(?P<id2>\d+)/(?:(?P<id3>\d+))?(?:/(?P<id4>\d+)/?)?$')
In [13]: import re
KeyboardInterrupt
In [13]: p.match('something/1/2/3/4').groups()
Out[13]: ('1', '2', '3', '4')
In [14]: p.match('something/1/2/3/').groups()
Out[14]: ('1', '2', '3', None)
In [15]: p.match('something/1/2/3').groups()
Out[15]: ('1', '2', '3', None)
In [16]: p.match('something/1/2/').groups()
Out[16]: ('1', '2', None, None)