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
|
/**
*
*/
package cgeo.geocaching.utils;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Misc. utils
*/
public final class BaseUtils {
/**
* Searches for the pattern p in the data. If the pattern is not found defaultValue is returned
*
* @param data
* Data to search in
* @param p
* Pattern to search for
* @param group
* Number of the group to return if found
* @param defaultValue
* Value to return if the pattern is not found
* @return defaultValue or the n-th group if the pattern matches (trimed)
*/
public static String getMatch(final String data, final Pattern p, final int group, final String defaultValue) {
final Matcher matcher = p.matcher(data);
if (matcher.find() && matcher.groupCount() >= group) {
return new String(matcher.group(group).trim());
// Java copies the whole page String, when matching with regular expressions
// later this would block the garbage collector, as we only need tiny parts of the page
// see http://developer.android.com/reference/java/lang/String.html#backing_array
// And BTW: You cannot even see that effect in the debugger, but must use a separate memory profiler!
}
return defaultValue;
}
/**
* Searches for the pattern p in the data. If the pattern is not found defaultValue is returned
*
* @param data
* Data to search in
* @param p
* Pattern to search for
* @param trim
* Set to true if the group found should be trim'ed
* @param defaultValue
* Value to return if the pattern is not found
* @return defaultValue or the first group if the pattern matches (trimed if wanted)
*/
public static String getMatch(final String data, final Pattern p, final boolean trim, final String defaultValue) {
final Matcher matcher = p.matcher(data);
if (matcher.find() && matcher.groupCount() >= 1) {
if (trim) {
return new String(matcher.group(1).trim());
}
return new String(matcher.group(1));
// Java copies the whole page String, when matching with regular expressions
// later this would block the garbage collector, as we only need tiny parts of the page
// see http://developer.android.com/reference/java/lang/String.html#backing_array
// Thus the creating of a new String via String constructor is necessary here!!
// And BTW: You cannot even see that effect in the debugger, but must use a separate memory profiler!
}
return defaultValue;
}
/**
* @param data
* @param regex
* @return
*/
public static boolean matches(final String data, final Pattern p) {
return p.matcher(data).find();
}
/**
* Replaces every \n, \r and \t with a single space. Afterwards multiples spaces
* are merged into a single space. Finally leading spaces are deleted.
*
* This method must be fast, but may not lead to the shortest replacement String.
*
* You are only allowed to change this code if you can prove it became faster on a device.
* see cgeo.geocaching.test.WhiteSpaceTest#replaceWhitespaceManually in the test project
*
* @param data
* complete HTML page
* @return the HTML page as a very long single "line"
*/
public static String replaceWhitespace(final String data) {
final int length = data.length();
final char[] chars = new char[length];
data.getChars(0, length, chars, 0);
int resultSize = 0;
boolean lastWasWhitespace = true;
for (char c : chars) {
if (c == ' ' || c == '\n' || c == '\r' || c == '\t') {
if (!lastWasWhitespace) {
chars[resultSize++] = ' ';
}
lastWasWhitespace = true;
} else {
chars[resultSize++] = c;
lastWasWhitespace = false;
}
}
return String.valueOf(chars, 0, resultSize);
}
}
|