split1 Function

private pure function split1(str, token) result(vals)

Split a character string using a token. This routine is inspired by the Python split function.

Example

   character(len=:),allocatable :: s
   type(string),dimension(:),allocatable :: vals
   s = '1,2,3,4,5'
   call split(s,',',vals)

Arguments

Type IntentOptional Attributes Name
character(len=*), intent(in) :: str
character(len=*), intent(in) :: token

Return Value type(string), dimension(:), allocatable


Calls

proc~~split1~~CallsGraph proc~split1 aoc_utilities::split1 proc~expand_vector aoc_utilities::expand_vector proc~split1->proc~expand_vector

Called by

proc~~split1~~CalledByGraph proc~split1 aoc_utilities::split1 interface~split aoc_utilities::split interface~split->proc~split1 proc~split2 aoc_utilities::split2 interface~split->proc~split2 proc~split2->proc~split1 proc~go~2 problem_18::go proc~go~2->interface~split proc~go~8 problem_12::go proc~go~8->interface~split proc~initialize problem_22::initialize proc~initialize->interface~split proc~parse_nums64 aoc_utilities::parse_nums64 proc~parse_nums64->interface~split proc~parse_rule problem_19::parse_rule proc~parse_rule->interface~split proc~parse_rule~2 problem_19b::parse_rule proc~parse_rule~2->interface~split program~problem_12b problem_12b program~problem_12b->interface~split program~problem_15 problem_15 program~problem_15->interface~split program~problem_19 problem_19 program~problem_19->interface~split program~problem_19->proc~parse_rule program~problem_19b problem_19b program~problem_19b->interface~split program~problem_19b->proc~parse_rule~2 program~problem_2 problem_2 program~problem_2->interface~split program~problem_25 problem_25 program~problem_25->interface~split program~problem_4 problem_4 program~problem_4->interface~split program~problem_7 problem_7 program~problem_7->interface~split interface~parse aoc_utilities::parse interface~parse->proc~parse_nums64 program~problem_12 problem_12 program~problem_12->proc~go~8 program~problem_18 problem_18 program~problem_18->proc~go~2 program~problem_22 problem_22 program~problem_22->proc~initialize program~problem_9 problem_9 program~problem_9->interface~parse

Source Code

    pure function split1(str,token) result(vals)

    implicit none

    character(len=*),intent(in)  :: str
    character(len=*),intent(in)  :: token
    type(string),dimension(:),allocatable :: vals

    integer :: i          !! counter
    integer :: len_str    !! significant length of `str`
    integer :: len_token  !! length of the token
    integer :: n_tokens   !! number of tokens
    integer :: i1         !! index
    integer :: i2         !! index
    integer :: j          !! counters
    integer,dimension(:),allocatable :: itokens !! start indices of the
                                                !! token locations in `str`

    len_token = len(token)  ! length of the token
    n_tokens  = 0           ! initialize the token counter
    j         = 0           ! index to start looking for the next token

    ! first, count the number of times the token
    ! appears in the string, and get the token indices.
    !
    ! Examples:
    !  ',         '    --> 1
    !  '1234,67,90'    --> 5,8
    !  '123,      '    --> 4

    ! length of the string
    if (token == ' ') then
        ! in this case, we can't ignore trailing space
        len_str = len(str)
    else
        ! safe to ignore trailing space when looking for tokens
        len_str = len_trim(str)
    end if

    j = 1
    n_tokens = 0
    do
        if (j>len_str) exit      ! end of string, finished
        i = index(str(j:),token) ! index of next token in remaining string
        if (i<=0) exit           ! no more tokens found
        call expand_vector(itokens,n_tokens,i+j-1)  ! save the token location
        j = j + i + (len_token - 1)
    end do
    call expand_vector(itokens,n_tokens,finished=.true.)  ! resize the vector

    allocate(vals(n_tokens+1))

    if (n_tokens>0) then

        len_str = len(str)

        i1 = 1
        i2 = itokens(1)-1
        if (i2>=i1) then
            vals(1)%str = str(i1:i2)
        else
            vals(1)%str = ''  !the first character is a token
        end if

        !      1 2 3
        !    'a,b,c,d'

        do i=2,n_tokens
            i1 = itokens(i-1)+len_token
            i2 = itokens(i)-1
            if (i2>=i1) then
                vals(i)%str = str(i1:i2)
            else
                vals(i)%str = ''  !empty element (e.g., 'abc,,def')
            end if
        end do

        i1 = itokens(n_tokens) + len_token
        i2 = len_str
        if (itokens(n_tokens)+len_token<=len_str) then
            vals(n_tokens+1)%str = str(i1:i2)
        else
            vals(n_tokens+1)%str = ''  !the last character was a token
        end if

    else
        !no tokens present, so just return the original string:
        vals(1)%str = str
    end if

    end function split1