Here is an example of data:
'1.'    'Numeric types'
'1.1.'  'Integer'
'1.2.'  'Float'
...
'1.10'  'Double'
To naturally sort it we can use string_to_array with '.' as separator, then cast text[] to int[] and sort by integer array, but since the field itself is of type text and there might be cases where user decides to use non-numeric symbols, e.g. 1.1.3a, thus causing cast error.
To address that I decided to use regexp:
select regexp_matches('1.2.3.4.', E'(?:(\\d+)\.?)+')
Expected result is array: {'1', '2', '3', '4'} but instead i get only the last element of the said array, however, if I use following regexp:
select regexp_matches('1.2.3.4.', E'((?:\\d+)\.?)+')
The result is {'1.2.3.4.'}. 
Using global-flag 'g' is not an option, because regexp_matches returns a column.
Is there any way to convert '1.2.3.4a.'::text to {1, 2, 3 ,4}::int[] using only one regexp_matches?
                        
You can use the global
'g'flag withregexp_matches, but needs to aggregate values to an array (most simple with thearray()constructor):Or, you can split your string to array with
string_to_array(), but you still need to use regexp to remove any non-numeric characters:For a more advanced natural-like sorting, you need to split your text to tokens yourself. See more info at the related SO question.
I could come up with a simplified, reusable function:
With this function, natural sorting will be this easy:
SQLFiddle