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