Skip to content

Commit 0886501

Browse files
authored
Implement strip and chomp as supplement to trim (#343)
- strip function to remove whitespace set as defined by stdlib_ascii - chomp function to remove either trailing character sets or substrings
1 parent 928bb28 commit 0886501

8 files changed

+404
-3
lines changed

doc/specs/index.md

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ This is and index/directory of the specifications (specs) for each new module/fe
2222
- [stats](./stdlib_stats.html) - Descriptive Statistics
2323
- [stats_distribution_PRNG](./stdlib_stats_distribution_PRNG.html) - Probability Distributions random number generator
2424
- [string\_type](./stdlib_string_type.html) - Basic string support
25+
- [strings](./stdlib_strings.html) - String handling and manipulation routines
2526

2627
## Missing specs
2728

doc/specs/stdlib_strings.md

+110
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
---
2+
title: string handling
3+
---
4+
5+
# The `stdlib_strings` module
6+
7+
[TOC]
8+
9+
## Introduction
10+
11+
The `stdlib_strings` module provides basic string handling and manipulation routines.
12+
13+
14+
## Procedures and methods provided
15+
16+
17+
<!-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -->
18+
### `strip`
19+
20+
#### Description
21+
22+
Remove leading and trailing whitespace characters.
23+
24+
#### Syntax
25+
26+
`string = [[stdlib_strings(module):strip(interface)]] (string)`
27+
28+
#### Status
29+
30+
Experimental
31+
32+
#### Class
33+
34+
Pure function.
35+
36+
#### Argument
37+
38+
- `string`: Character scalar or [[stdlib_string_type(module):string_type(type)]].
39+
This argument is intent(in).
40+
41+
#### Result value
42+
43+
The result is of the same type as `string`.
44+
45+
#### Example
46+
47+
```fortran
48+
program demo
49+
use stdlib_ascii, only : TAB, VT, NUL, LF, CR, FF
50+
use stdlib_strings, only : strip
51+
implicit none
52+
print'(a)', strip(" hello ") ! "hello"
53+
print'(a)', strip(TAB//"goodbye"//CR//LF) ! "goodbye"
54+
print'(a)', strip(" "//TAB//LF//VT//FF//CR) ! ""
55+
print'(a)', strip(" ! ")//"!" ! "!!"
56+
print'(a)', strip("Hello") ! "Hello"
57+
end program demo
58+
```
59+
60+
61+
<!-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -->
62+
### `chomp`
63+
64+
#### Description
65+
66+
Remove trailing characters in *set* or *substring* from *string*.
67+
If no character *set* or *substring* is provided trailing whitespace is removed.
68+
69+
#### Syntax
70+
71+
`string = [[stdlib_strings(module):chomp(interface)]] (string[, set|substring])`
72+
73+
#### Status
74+
75+
Experimental
76+
77+
#### Class
78+
79+
Pure function.
80+
81+
#### Argument
82+
83+
- `string`: Character scalar or [[stdlib_string_type(module):string_type(type)]].
84+
This argument is intent(in).
85+
- `set`: Array of length one character. This argument is intent(in).
86+
- `substring`: Character scalar or [[stdlib_string_type(module):string_type(type)]].
87+
This argument is intent(in).
88+
89+
#### Result value
90+
91+
The result is of the same type as `string`.
92+
93+
#### Example
94+
95+
```fortran
96+
program demo
97+
use stdlib_ascii, only : TAB, VT, NUL, LF, CR, FF
98+
use stdlib_strings, only : chomp
99+
implicit none
100+
print'(a)', chomp(" hello ") ! " hello"
101+
print'(a)', chomp(TAB//"goodbye"//CR//LF) ! "\tgoodbye"
102+
print'(a)', chomp(" "//TAB//LF//VT//FF//CR) ! ""
103+
print'(a)', chomp(" ! ")//"!" ! " !!"
104+
print'(a)', chomp("Hello") ! "Hello"
105+
print'(a)', chomp("hello", ["l", "o"]) ! "he"
106+
print'(a)', chomp("hello", set=["l", "o"]) ! "he"
107+
print'(a)', chomp("hello", "lo") ! "hel"
108+
print'(a)', chomp("hello", substring="lo") ! "hel"
109+
end program demo
110+
```

src/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ set(SRC
4242
stdlib_kinds.f90
4343
stdlib_logger.f90
4444
stdlib_string_type.f90
45+
stdlib_strings.f90
4546
stdlib_system.F90
4647
${outFiles}
4748
)

src/Makefile.manual

+3-1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ SRC = f18estop.f90 \
2525
stdlib_error.f90 \
2626
stdlib_kinds.f90 \
2727
stdlib_logger.f90 \
28+
stdlib_strings.f90 \
2829
stdlib_string_type.f90 \
2930
$(SRCGEN)
3031

@@ -109,4 +110,5 @@ stdlib_stats_var.o: \
109110
stdlib_stats_distribution_PRNG.o: \
110111
stdlib_kinds.o \
111112
stdlib_error.o
112-
stdlib_string_type.o: stdlib_ascii.o
113+
stdlib_string_type.o: stdlib_ascii.o
114+
stdlib_strings.o: stdlib_ascii.o stdlib_string_type.o

src/stdlib_strings.f90

+176
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
! SPDX-Identifier: MIT
2+
3+
!> This module implements basic string handling routines.
4+
!>
5+
!> The specification of this module is available [here](../page/specs/stdlib_strings.html).
6+
module stdlib_strings
7+
use stdlib_ascii, only : whitespace
8+
use stdlib_string_type, only : string_type, char, verify
9+
implicit none
10+
private
11+
12+
public :: strip, chomp
13+
14+
15+
!> Remove leading and trailing whitespace characters.
16+
!>
17+
!> Version: experimental
18+
interface strip
19+
module procedure :: strip_string
20+
module procedure :: strip_char
21+
end interface strip
22+
23+
!> Remove trailing characters in set from string.
24+
!> If no character set is provided trailing whitespace is removed.
25+
!>
26+
!> Version: experimental
27+
interface chomp
28+
module procedure :: chomp_string
29+
module procedure :: chomp_char
30+
module procedure :: chomp_set_string_char
31+
module procedure :: chomp_set_char_char
32+
module procedure :: chomp_substring_string_string
33+
module procedure :: chomp_substring_char_string
34+
module procedure :: chomp_substring_string_char
35+
module procedure :: chomp_substring_char_char
36+
end interface chomp
37+
38+
39+
contains
40+
41+
42+
!> Remove leading and trailing whitespace characters.
43+
pure function strip_string(string) result(stripped_string)
44+
! Avoid polluting the module scope and use the assignment only in this scope
45+
use stdlib_string_type, only : assignment(=)
46+
type(string_type), intent(in) :: string
47+
type(string_type) :: stripped_string
48+
49+
stripped_string = strip(char(string))
50+
end function strip_string
51+
52+
!> Remove leading and trailing whitespace characters.
53+
pure function strip_char(string) result(stripped_string)
54+
character(len=*), intent(in) :: string
55+
character(len=:), allocatable :: stripped_string
56+
integer :: first, last
57+
58+
first = verify(string, whitespace)
59+
if (first == 0) then
60+
stripped_string = ""
61+
else
62+
last = verify(string, whitespace, back=.true.)
63+
stripped_string = string(first:last)
64+
end if
65+
66+
end function strip_char
67+
68+
69+
!> Remove trailing characters in set from string.
70+
!> Default character set variant where trailing whitespace is removed.
71+
pure function chomp_string(string) result(chomped_string)
72+
! Avoid polluting the module scope and use the assignment only in this scope
73+
use stdlib_string_type, only : assignment(=)
74+
type(string_type), intent(in) :: string
75+
type(string_type) :: chomped_string
76+
integer :: last
77+
78+
last = verify(string, whitespace, back=.true.)
79+
chomped_string = char(string, 1, last)
80+
end function chomp_string
81+
82+
!> Remove trailing characters in set from string.
83+
!> Default character set variant where trailing whitespace is removed.
84+
pure function chomp_char(string) result(chomped_string)
85+
character(len=*), intent(in) :: string
86+
character(len=:), allocatable :: chomped_string
87+
integer :: last
88+
89+
last = verify(string, whitespace, back=.true.)
90+
chomped_string = string(1:last)
91+
end function chomp_char
92+
93+
!> Remove trailing characters in set from string.
94+
pure function chomp_set_string_char(string, set) result(chomped_string)
95+
! Avoid polluting the module scope and use the assignment only in this scope
96+
use stdlib_string_type, only : assignment(=)
97+
type(string_type), intent(in) :: string
98+
character(len=1), intent(in) :: set(:)
99+
type(string_type) :: chomped_string
100+
101+
chomped_string = chomp(char(string), set)
102+
end function chomp_set_string_char
103+
104+
!> Remove trailing characters in set from string.
105+
pure function chomp_set_char_char(string, set) result(chomped_string)
106+
character(len=*), intent(in) :: string
107+
character(len=1), intent(in) :: set(:)
108+
character(len=:), allocatable :: chomped_string
109+
integer :: last
110+
111+
last = verify(string, set_to_string(set), back=.true.)
112+
chomped_string = string(1:last)
113+
114+
end function chomp_set_char_char
115+
116+
!> Remove trailing substrings from string.
117+
pure function chomp_substring_string_string(string, substring) result(chomped_string)
118+
! Avoid polluting the module scope and use the assignment only in this scope
119+
use stdlib_string_type, only : assignment(=)
120+
type(string_type), intent(in) :: string
121+
type(string_type), intent(in) :: substring
122+
type(string_type) :: chomped_string
123+
124+
chomped_string = chomp(char(string), char(substring))
125+
end function chomp_substring_string_string
126+
127+
!> Remove trailing substrings from string.
128+
pure function chomp_substring_string_char(string, substring) result(chomped_string)
129+
! Avoid polluting the module scope and use the assignment only in this scope
130+
use stdlib_string_type, only : assignment(=)
131+
type(string_type), intent(in) :: string
132+
character(len=*), intent(in) :: substring
133+
type(string_type) :: chomped_string
134+
135+
chomped_string = chomp(char(string), substring)
136+
end function chomp_substring_string_char
137+
138+
!> Remove trailing substrings from string.
139+
pure function chomp_substring_char_string(string, substring) result(chomped_string)
140+
character(len=*), intent(in) :: string
141+
type(string_type), intent(in) :: substring
142+
character(len=:), allocatable :: chomped_string
143+
144+
chomped_string = chomp(string, char(substring))
145+
end function chomp_substring_char_string
146+
147+
!> Remove trailing substrings from string.
148+
pure function chomp_substring_char_char(string, substring) result(chomped_string)
149+
character(len=*), intent(in) :: string
150+
character(len=*), intent(in) :: substring
151+
character(len=:), allocatable :: chomped_string
152+
integer :: last, nsub
153+
154+
last = len(string)
155+
nsub = len(substring)
156+
if (nsub > 0) then
157+
do while(string(last-nsub+1:last) == substring)
158+
last = last - nsub
159+
end do
160+
end if
161+
chomped_string = string(1:last)
162+
163+
end function chomp_substring_char_char
164+
165+
!> Implementation to transfer a set of characters to a string representing the set.
166+
!>
167+
!> This function is internal and not part of the public API.
168+
pure function set_to_string(set) result(string)
169+
character(len=1), intent(in) :: set(:)
170+
character(len=size(set)) :: string
171+
172+
string = transfer(set, string)
173+
end function set_to_string
174+
175+
176+
end module stdlib_strings

src/tests/string/CMakeLists.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@ ADDTEST(string_operator)
33
ADDTEST(string_intrinsic)
44
ADDTEST(string_derivedtype_io)
55
ADDTEST(string_functions)
6-
6+
ADDTEST(string_strip_chomp)

src/tests/string/Makefile.manual

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ PROGS_SRC = test_string_assignment.f90 \
22
test_string_derivedtype_io.f90 \
33
test_string_functions.f90 \
44
test_string_intrinsic.f90 \
5-
test_string_operator.f90
5+
test_string_operator.f90 \
6+
test_string_strip_chomp.f90
67

78

89
include ../Makefile.manual.test.mk

0 commit comments

Comments
 (0)