@@ -13,6 +13,9 @@ module string_module
1313 character (len=* ),parameter :: upper = ' ABCDEFGHIJKLMNOPQRSTUVWXYZ' ! ! uppercase characters
1414
1515 public :: lowercase,uppercase
16+ public :: replace_char
17+ public :: reverse
18+ public :: lchop, rchop
1619
1720 contains
1821! *****************************************************************************************
@@ -21,16 +24,14 @@ module string_module
2124! >
2225! Convert the string to uppercase.
2326
24- subroutine uppercase (str )
25-
26- implicit none
27+ pure subroutine uppercase (str )
2728
2829 character (len=* ),intent (inout ) :: str
2930
3031 integer :: i,idx
3132
3233 do i= 1 ,len_trim (str)
33- idx = index (str(i:i),lower )
34+ idx = index (lower, str(i:i))
3435 if (idx> 0 ) str(i:i) = upper(idx:idx)
3536 end do
3637
@@ -41,21 +42,116 @@ end subroutine uppercase
4142! >
4243! Convert the string to lowercase.
4344
44- subroutine lowercase (str )
45-
46- implicit none
45+ pure subroutine lowercase (str )
4746
4847 character (len=* ),intent (inout ) :: str
4948
5049 integer :: i,idx
5150
5251 do i= 1 ,len_trim (str)
53- idx = index (str(i:i),upper )
52+ idx = index (upper, str(i:i))
5453 if (idx> 0 ) str(i:i) = lower(idx:idx)
5554 end do
5655
5756 end subroutine lowercase
5857! *****************************************************************************************
5958
60- end module string_module
6159! *****************************************************************************************
60+ ! >
61+ ! Replace all occurrences of a single character `s1` in `str` with `s2`.
62+
63+ pure function replace_char (str , s1 , s2 ) result(newstr)
64+
65+ character (len=* ),intent (in ) :: str ! ! original string
66+ character (len= 1 ),intent (in ) :: s1 ! ! find all occurrences of this character
67+ character (len= 1 ),intent (in ) :: s2 ! ! replace with this character
68+ character (len= :),allocatable :: newstr ! ! new string
69+
70+ integer :: i ! ! counter
71+
72+ newstr = str
73+ do i = 1 , len (newstr)
74+ if (newstr(i:i) == s1) newstr(i:i) = s2
75+ end do
76+
77+ end function replace_char
78+ ! *****************************************************************************************
79+
80+ ! *****************************************************************************************
81+ ! >
82+ ! Chop leading `chars` string from `str`.
83+ ! Note that trailing spaces are not ignored in either string.
84+
85+ pure function lchop (str , chars ) result(newstr)
86+
87+ character (len=* ),intent (in ) :: str ! ! original string
88+ character (len=* ),intent (in ) :: chars ! ! characters to strip
89+ character (len= :),allocatable :: newstr ! ! new string
90+
91+ ! this logic here is to account for trailing spaces, which we preserve
92+ if (len (chars)>len (str)) then
93+ newstr = str ! not possible to chop
94+ else
95+ if (str== chars) then
96+ if (len (str)>len (chars)) then
97+ newstr = str(len (chars)+ 1 :) ! only trailing spaces remain
98+ else
99+ newstr = ' ' ! string is now empty
100+ end if
101+ else
102+ if (index (str,chars) == 1 ) then
103+ newstr = str(len (chars)+ 1 :) ! chop leading chars, keep rest of string
104+ else
105+ newstr = str ! original string, noting to chop
106+ end if
107+ end if
108+ end if
109+
110+ end function lchop
111+ ! *****************************************************************************************
112+
113+ ! *****************************************************************************************
114+ ! >
115+ ! Chop trailing `chars` string from `str`.
116+ ! Note that trailing spaces are not ignored in either string.
117+
118+ pure function rchop (str , chars ) result(newstr)
119+
120+ character (len=* ),intent (in ) :: str ! ! original string
121+ character (len=* ),intent (in ) :: chars ! ! characters to strip
122+ character (len= :),allocatable :: newstr ! ! new string
123+
124+ newstr = reverse(lchop(reverse(str), reverse(chars)))
125+
126+ end function rchop
127+ ! *****************************************************************************************
128+
129+ ! *****************************************************************************************
130+ ! >
131+ ! Reverse a string.
132+
133+ pure function reverse (str ) result(newstr)
134+
135+ character (len=* ),intent (in ) :: str ! ! original string
136+ character (len= :),allocatable :: newstr ! ! new string
137+ integer :: i, j ! ! counter
138+ integer :: n ! ! length of `str`
139+
140+ n = len (str)
141+ allocate (character (len= n) :: newstr)
142+ if (n== 0 ) then
143+ newstr = ' '
144+ else
145+ j = 0
146+ do i = n, 1 , - 1
147+ j = j + 1
148+ newstr(j:j) = str(i:i)
149+ end do
150+ end if
151+
152+ end function reverse
153+ ! *****************************************************************************************
154+
155+ ! *****************************************************************************************
156+ end module string_module
157+ ! *****************************************************************************************
0 commit comments