search Function

private function search(self, tag_start, tag_end, in_string, in_character, istart, iend) result(tag)

Search for tagged record into string, return the first record found (if any) matching the tags.

Optionally, returns the indexes of tag start/end, thus this is not an elemental function.

 type(string)                  :: astring
 type(string)                  :: anotherstring
 character(len=:), allocatable :: acharacter
 integer                       :: istart
 integer                       :: iend
 logical                       :: test_passed(5)
 astring = '<test> <first> hello </first> <first> not the first </first> </test>'
 anotherstring = astring%search(tag_start='<first>', tag_end='</first>')
 test_passed(1) = anotherstring//''=='<first> hello </first>'
 astring = '<test> <a> <a> <a> the nested a </a> </a> </a> </test>'
 anotherstring = astring%search(tag_start='<a>', tag_end='</a>')
 test_passed(2) = anotherstring//''=='<a> <a> <a> the nested a </a> </a> </a>'
 call astring%free
 anotherstring = '<test> <a> <a> <a> the nested a </a> </a> </a> </test>'
 astring = astring%search(in_string=anotherstring, tag_start='<a>', tag_end='</a>')
 test_passed(3) = astring//''=='<a> <a> <a> the nested a </a> </a> </a>'
 call astring%free
 acharacter = '<test> <a> <a> <a> the nested a </a> </a> </a> </test>'
 astring = astring%search(in_character=acharacter, tag_start='<a>', tag_end='</a>')
 test_passed(4) = astring//''=='<a> <a> <a> the nested a </a> </a> </a>'
 acharacter = '<test> <first> hello </first> <sec> <sec>not the first</sec> </sec> </test>'
 astring = astring%search(in_character=acharacter, tag_start='<sec>', tag_end='</sec>', istart=istart, iend=iend)
 test_passed(5) = astring//''==acharacter(31:67)
 print '(L1)', all(test_passed)

Type Bound

string

Arguments

Type IntentOptional Attributes Name
class(string), intent(in) :: self

The string.

character(kind=CK, len=*), intent(in) :: tag_start

Start tag.

character(kind=CK, len=*), intent(in) :: tag_end

End tag.

type(string), intent(in), optional :: in_string

Search into this string.

character(kind=CK, len=*), intent(in), optional :: in_character

Search into this character string.

integer, intent(out), optional :: istart

Starting index of tag inside the string.

integer, intent(out), optional :: iend

Ending index of tag inside the string.

Return Value type(string)

First tag found.


Contents

Source Code


Source Code

   function search(self, tag_start, tag_end, in_string, in_character, istart, iend) result(tag)
   !< Search for *tagged* record into string, return the first record found (if any) matching the tags.
   !<
   !< Optionally, returns the indexes of tag start/end, thus this is not an `elemental` function.
   !<
   !< @note The tagged record is searched into self if allocated otherwise into `in_string` if passed or, eventually, into
   !< `in_character` is passed. If tag is not found the return string is not allocated and the start/end indexes (if requested) are
   !< zero.
   !<
   !<```fortran
   !< type(string)                  :: astring
   !< type(string)                  :: anotherstring
   !< character(len=:), allocatable :: acharacter
   !< integer                       :: istart
   !< integer                       :: iend
   !< logical                       :: test_passed(5)
   !< astring = '<test> <first> hello </first> <first> not the first </first> </test>'
   !< anotherstring = astring%search(tag_start='<first>', tag_end='</first>')
   !< test_passed(1) = anotherstring//''=='<first> hello </first>'
   !< astring = '<test> <a> <a> <a> the nested a </a> </a> </a> </test>'
   !< anotherstring = astring%search(tag_start='<a>', tag_end='</a>')
   !< test_passed(2) = anotherstring//''=='<a> <a> <a> the nested a </a> </a> </a>'
   !< call astring%free
   !< anotherstring = '<test> <a> <a> <a> the nested a </a> </a> </a> </test>'
   !< astring = astring%search(in_string=anotherstring, tag_start='<a>', tag_end='</a>')
   !< test_passed(3) = astring//''=='<a> <a> <a> the nested a </a> </a> </a>'
   !< call astring%free
   !< acharacter = '<test> <a> <a> <a> the nested a </a> </a> </a> </test>'
   !< astring = astring%search(in_character=acharacter, tag_start='<a>', tag_end='</a>')
   !< test_passed(4) = astring//''=='<a> <a> <a> the nested a </a> </a> </a>'
   !< acharacter = '<test> <first> hello </first> <sec> <sec>not the first</sec> </sec> </test>'
   !< astring = astring%search(in_character=acharacter, tag_start='<sec>', tag_end='</sec>', istart=istart, iend=iend)
   !< test_passed(5) = astring//''==acharacter(31:67)
   !< print '(L1)', all(test_passed)
   !<```
   !=> T <<<
   class(string),             intent(in)            :: self         !< The string.
   character(kind=CK, len=*), intent(in)            :: tag_start    !< Start tag.
   character(kind=CK, len=*), intent(in)            :: tag_end      !< End tag.
   type(string),              intent(in),  optional :: in_string    !< Search into this string.
   character(kind=CK, len=*), intent(in),  optional :: in_character !< Search into this character string.
   integer,                   intent(out), optional :: istart       !< Starting index of tag inside the string.
   integer,                   intent(out), optional :: iend         !< Ending index of tag inside the string.
   type(string)                                     :: tag          !< First tag found.
   character(kind=CK, len=:), allocatable           :: raw          !< Raw string into which search the tag.
   integer                                          :: istart_      !< Starting index of tag inside the string, local variable.
   integer                                          :: iend_        !< Ending index of tag inside the string, local variable.
   integer                                          :: nested_tags  !< Number of nested tags inside tag.
   integer                                          :: t            !< Counter.

   raw = ''
   if (present(in_string)) then
      raw = in_string%raw
   elseif (present(in_character)) then
      raw = in_character
   else
      if (allocated(self%raw)) raw = self%raw
   endif
   istart_ = 0
   iend_ = 0
   if (raw/='') then
      istart_ = index(raw, tag_start)
      iend_ = index(raw, tag_end)
      if (istart_>0.and.iend_>0) then
         iend_ = iend_ + len(tag_end) - 1
         tag%raw = raw(istart_:iend_)
         nested_tags = tag%count(tag_start)
         if (nested_tags>1) then
            do t=2, nested_tags
               iend_ = iend_ + len(tag_end) - 1 + index(raw(iend_+1:), tag_end)
            enddo
            tag%raw = raw(istart_:iend_)
         endif
      endif
   endif
   if (present(istart)) istart = istart_
   if (present(iend)) iend = iend_
   endfunction search