File: StringUtil.java

package info (click to toggle)
beagle 241217-3
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 9,712 kB
  • sloc: java: 17,684; sh: 55; makefile: 11
file content (281 lines) | stat: -rw-r--r-- 10,234 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
/*
 * Copyright (C) 2014-2021 Brian L. Browning
 *
 * This file is part of Beagle
 *
 * Beagle is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Beagle is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package blbutil;

/**
 * Class {@code StringUtil} is a utility class with static methods
 * for counting and returning delimited fields in a string.
 *
 * @author Brian L. Browning {@code <browning@uw.edu>}
 */
public class StringUtil {

    /* Private constructor to prevent instantiation */
    private StringUtil() {
    }

    /**
     * Returns the number of delimited fields in the specified
     * string.  Returns 0 if the specified string has length 0.
     *
     * @param s a string
     * @param delimiter a delimiter character
     * @return the number of delimited fields in the specified string
     * @throws NullPointerException if {@code s == null}
     */
    public static int countFields(String s, char delimiter) {
        int cnt = 0;
        for (int j=0, n=s.length(); j<n; ++j) {
            if (s.charAt(j)==delimiter) {
                ++cnt;
            }
        }
        return cnt + 1;
    }

    /**
     * Returns {@code Math.min(countFields(s, delimiter), max)}.
     *
     * @param s a string with 0 or more {@code delimiter} characters
     * @param delimiter the delimiter character
     * @param max the maximum value that can be returned
     *
     * @return {@code Math.min(countFields(s, delimiter), max)}
     *
     * @throws NullPointerException if {@code s == null}
     */
    public static int countFields(String s, char delimiter, int max) {
        int cnt = 0;
        int maxCnt = max - 1;
        for (int j=0, n=s.length(); j<n && cnt<maxCnt; ++j) {
            if (s.charAt(j)==delimiter) {
                ++cnt;
            }
        }
        return Math.min(cnt + 1, max);
    }

    /**
     * Returns an array obtained by splitting the specified string
     * around the specified delimiter.
     * The array returned by this method contains each substring of
     * the string that does not contain the delimiter and that
     * is preceded by the delimiter or the beginning of
     * the string and that is terminated by the delimiter or the end
     * of the string.  The substrings in the array are in
     * the order in which they occur in the specified string.
     * If there are no delimiters in the specified string then the method
     * return an array of length one, whose single element is the specified
     * string.
     *
     * @param s a string
     * @param delimiter a delimiter character
     *
     * @return the array of strings obtained by splitting the specified string
     * around the specified delimiter
     *
     * @throws NullPointerException if {@code s == null}
     */
    public static String[] getFields(String s, char delimiter) {
        String[] fields = new String[countFields(s, delimiter)];
        int start = 0;
        for (int j=0; j<fields.length; ++j)  {
            int end = s.indexOf(delimiter, start);
            fields[j] = end>=0 ? s.substring(start,end) : s.substring(start);
            start = end + 1;
        }
        return fields;
    }

    /**
     * Returns an array obtained by splitting the specified string
     * around the first {@code (limit - 1)} occurrences of the specified
     * delimiter.  If the string contains fewer than {@code (limit - 1)}
     * delimiter characters, the returned value will equal
     * {@code StringUtil.getFields(s, delimiter)}
     *
     * @param s a string
     * @param delimiter a delimiter character
     * @param limit the maximum length of the returned array
     *
     * @return an array obtained by splitting the specified string
     * around the specified delimiter
     *
     * @throws NullPointerException if {@code s == null}
     * @throws IllegalArgumentException if {@code limit < 2 }
     */
    public static String[] getFields(String s, char delimiter, int limit) {
        if (limit < 2) {
            throw new IllegalArgumentException("limit: " + limit);
        }
        String[] fields = new String[countFields(s, delimiter, limit)];
        if (fields.length > 0) {
            int start = 0;
            for (int j=0, n=fields.length-1; j<n; ++j)  {
                int end = s.indexOf(delimiter, start);
                fields[j] = s.substring(start, end);
                start = end + 1;
            }
            fields[fields.length - 1] = s.substring(start);
        }
        return fields;
    }

    /**
     * Returns the number of white-space delimited fields in the specified
     * string.  A field is a maximal set of consecutive characters that are not
     * white space characters.  White space is defined as any unicode
     * characters less than or equal to '&#92;u0020'.
     *
     * @param s a string
     * @return the number of white-space delimited fields in the specified
     * string
     * @throws NullPointerException if {@code s == null}
     */
    public static int countFields(String s) {
        int start = 0;
        int end = s.length();
        while (start<end && s.charAt(start)<=' ') {
            ++start;
        }
        while (end>start && s.charAt(end-1)<=' ') {
            --end;
        }
        int fieldCount = (start<end) ? 1 : 0;
        while (++start<end && s.charAt(start)>' ') {
        }
        while (start<end) {
            while (s.charAt(++start)<=' ') {
            }
            ++fieldCount;
            while (++start<end && s.charAt(start)>' ') {
            }
        }
        return fieldCount;
    }

    /**
     * Returns an array obtained by trimming white-space from the
     * beginning and end of the specified string, and splitting the resulting
     * string around white space.
     * White space is any maximal substring of unicode characters
     * less than or equal to '&#92;u0020'. White-space at the beginning and
     * end of the string is ignored.  The substrings in the returned array
     * are in the order in which they occur in this string.  If there is no
     * white-space in the specified string, the method returns an array
     * of length one whose single element is the trimmed string.  If the
     * specified string contains only white-space a string array
     * of length 0 is returned.
     *
     * @param s a string
     * @return the array of strings obtained by splitting the specified string
     * around white space
     *
     * @throws NullPointerException if {@code s == null}
     */
    public static String[] getFields(String s) {
        s = s.trim();
        int n = s.length();
        String[] fields = new String[countFields(s)];
        if (fields.length > 0) {
            int index = 0;
            int start = 0;
            int j = -1;
            while (++j<n && s.charAt(j)>' ')  {
            }
            fields[index++] = s.substring(start, j);
            while (j<n) {
                while (s.charAt(++j)<=' ') {
                }
                start = j;
                while (++j<n && s.charAt(j)>' ') {
                }
                fields[index++] = s.substring(start, j);
            }
            assert index==fields.length;
        }
        return fields;
    }

    /**
     * <p>Returns an array obtained by trimming white-space from the
     * beginning and end of the specified string, and splitting the resulting
     * string around the first {@code (limit-1)} white-space delimiters.
     * A white-space delimiter is any maximal substring of unicode characters
     * less than or equal to '&#92;u0020'.  If the trimmed string contains
     * fewer than {@code (limit - 1)} white space delimiters, the returned value
     * will equal {@code StringUtil.getFields(s)}.  The substrings in the
     * returned array are in the order in which they occur in this string.
     * If there are no white-space delimiters in the specified string, the
     * method returns an array of length one whose single element is the
     * trimmed string. If the specified string contains only white-space,
     * a string array of length 0 is returned.
     *</p>
     *
     * @param s a string
     * @param limit the maximum length of the returned array
     *
     * @return the array of strings obtained by splitting the specified string
     * around white space
     *
     * @throws NullPointerException if {@code s == null}
     * @throws IllegalArgumentException if {@code limit < 2}
     */
    public static String[] getFields(String s, int limit) {
        if (limit<2) {
            throw new IllegalArgumentException("limit: " + limit);
        }
        s = s.trim();
        int n = s.length();
        int j=-1;
        while (++j<n && s.charAt(j)>' ') {
        }
        int fieldCount = (j>0) ? 1 : 0;
        while (j<n && fieldCount<limit) {
            while (s.charAt(++j)<=' ') {
            }
            ++fieldCount;
            while (++j<n && s.charAt(j)>' ') {
            }
        }
        String[] fields = new String[fieldCount];
        if (fields.length>0) {
            int index = 0;
            int start = 0;
            j = -1;
            while (++j<n && s.charAt(j)>' ') {
            }
            fields[index++] = s.substring(start, j);
            while (j<n && index<limit) {
                while (s.charAt(++j)<=' ') {
                }
                start = j;
                while (++j<n && s.charAt(j)>' ') {
                }
                if (index < limit-1) {
                    fields[index++] = s.substring(start, j);
                }
                else {
                    fields[index++] = s.substring(start);
                }
            }
        }
        return fields;
    }
}