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 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.
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 | Intent | Optional | 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. |
First tag found.
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