pure subroutine split(self, tokens, sep, max_tokens)
!< Return a list of substring in the string, using sep as the delimiter string.
!<
!< @note Multiple subsequent separators are collapsed to one occurrence.
!<
!< @note If `max_tokens` is passed the returned number of tokens is either `max_tokens` or `max_tokens + 1`.
!<
!<```fortran
!< type(string) :: astring
!< type(string), allocatable :: strings(:)
!< logical :: test_passed(11)
!< astring = '+ab-++cre-++cre-ab+'
!< call astring%split(tokens=strings, sep='+')
!< test_passed(1) = (strings(1)//''=='ab-'.and.strings(2)//''=='cre-'.and.strings(3)//''=='cre-ab')
!< astring = 'ab-++cre-++cre-ab+'
!< call astring%split(tokens=strings, sep='+')
!< test_passed(2) = (strings(1)//''=='ab-'.and.strings(2)//''=='cre-'.and.strings(3)//''=='cre-ab')
!< astring = 'ab-++cre-++cre-ab'
!< call astring%split(tokens=strings, sep='+')
!< test_passed(3) = (strings(1)//''=='ab-'.and.strings(2)//''=='cre-'.and.strings(3)//''=='cre-ab')
!< astring = 'Hello '//new_line('a')//'World!'
!< call astring%split(tokens=strings, sep=new_line('a'))
!< test_passed(4) = (strings(1)//''=='Hello '.and.strings(2)//''=='World!')
!< astring = 'Hello World!'
!< call astring%split(tokens=strings)
!< test_passed(5) = (strings(1)//''=='Hello'.and.strings(2)//''=='World!')
!< astring = '+ab-'
!< call astring%split(tokens=strings, sep='+')
!< test_passed(6) = (strings(1)//''=='ab-')
!< astring = '+ab-'
!< call astring%split(tokens=strings, sep='-')
!< test_passed(7) = (strings(1)//''=='+ab')
!< astring = '+ab-+cd-'
!< call astring%split(tokens=strings, sep='+')
!< test_passed(8) = (strings(1)//''=='ab-'.and.strings(2)//''=='cd-')
!< astring = 'ab-+cd-+'
!< call astring%split(tokens=strings, sep='+')
!< test_passed(9) = (strings(1)//''=='ab-'.and.strings(2)//''=='cd-')
!< astring = '+ab-+cd-+'
!< call astring%split(tokens=strings, sep='+')
!< test_passed(10) = (strings(1)//''=='ab-'.and.strings(2)//''=='cd-')
!< astring = '1-2-3-4-5-6-7-8'
!< call astring%split(tokens=strings, sep='-', max_tokens=3)
!< test_passed(11) = (strings(1)//''=='1'.and.strings(2)//''=='2'.and.strings(3)//''=='3'.and.strings(4)//''=='4-5-6-7-8')
!< print '(L1)', all(test_passed)
!<```
!=> T <<<
class(string), intent(in) :: self !< The string.
type(string), allocatable, intent(out) :: tokens(:) !< Tokens substring.
character(kind=CK, len=*), intent(in), optional :: sep !< Separator.
integer, intent(in), optional :: max_tokens !< Fix the maximum number of returned tokens.
character(kind=CK, len=:), allocatable :: sep_ !< Separator, default value.
integer :: No !< Number of occurrences of sep.
integer :: t !< Character counter.
type(string) :: temporary !< Temporary storage.
type(string), allocatable :: temp_toks(:,:) !< Temporary tokens substring.
if (allocated(self%raw)) then
sep_ = SPACE ; if (present(sep)) sep_ = sep
temporary = self%unique(sep_)
No = temporary%count(sep_)
if (No>0) then
if (present(max_tokens)) then
if (max_tokens < No.and.max_tokens > 0) No = max_tokens
endif
allocate(temp_toks(3, No))
temp_toks(:, 1) = temporary%partition(sep_)
if (No>1) then
do t=2, No
temp_toks(:, t) = temp_toks(3, t-1)%partition(sep_)
enddo
endif
if (temp_toks(1, 1)%raw/=''.and.temp_toks(3, No)%raw/='') then
allocate(tokens(No+1))
do t=1, No
if (t==No) then
tokens(t ) = temp_toks(1, t)
tokens(t+1) = temp_toks(3, t)
else
tokens(t) = temp_toks(1, t)
endif
enddo
elseif (temp_toks(1, 1)%raw/='') then
allocate(tokens(No))
do t=1, No
tokens(t) = temp_toks(1, t)
enddo
elseif (temp_toks(3, No)%raw/='') then
allocate(tokens(No))
do t=1, No-1
tokens(t) = temp_toks(1, t+1)
enddo
tokens(No) = temp_toks(3, No)
else
allocate(tokens(No-1))
do t=2, No
tokens(t-1) = temp_toks(1, t)
enddo
endif
else
allocate(tokens(1))
tokens(1) = self
endif
endif
endsubroutine split