1 package org.jruby.util; 2 3 import java.util.regex.Matcher ; 4 import java.util.regex.Pattern ; 5 6 10 public class StringScanner { 11 12 private CharSequence string; 13 private Matcher matcher; 14 private int pos = 0; 15 private int lastPos = -1; 16 private int matchStart = -1; 17 private int matchEnd = -1; 18 19 22 public StringScanner() { 23 this(""); 24 } 25 26 public StringScanner(CharSequence string) { 27 this.string = string; 28 } 29 30 public boolean isEndOfString() { 31 return pos == string.length(); 32 } 33 34 public boolean isBeginningOfLine() { 35 return pos == 0 || string.charAt(pos - 1) == '\n'; 36 } 37 38 public CharSequence getString() { 39 return string; 40 } 41 42 private void resetMatchData() { 43 matcher = null; 44 matchStart = -1; 45 matchEnd = -1; 46 } 47 48 public void terminate() { 49 pos = string.length(); 50 lastPos = -1; 51 resetMatchData(); 52 } 53 54 public void reset() { 55 pos = 0; 56 lastPos = -1; 57 resetMatchData(); 58 } 59 60 public void setString(CharSequence string) { 61 this.string = string; 62 reset(); 63 } 64 65 public void append(CharSequence string) { 66 StringBuffer buf = new StringBuffer (); 67 buf.append(this.string); 69 buf.append(string); 70 this.string = buf.toString(); 71 } 72 73 public CharSequence rest() { 74 return string.subSequence(pos, string.length()); 75 } 76 77 public int getPos() { 78 return pos; 79 } 80 81 public void setPos(int pos) { 82 if (pos > string.length()) { 83 throw new IllegalArgumentException ("index out of range."); 84 } 85 this.pos = pos; 86 } 87 88 public char getChar() { 89 if (isEndOfString()) { 90 return 0; 91 } else { 92 matcher = null; 93 matchStart = pos; 94 matchEnd = pos + 1; 95 lastPos = pos; 96 return string.charAt(pos++); 97 } 98 } 99 100 public boolean matched() { 101 return matchStart > -1; 102 } 103 104 public CharSequence group(int n) { 105 if (!matched()) { 106 return null; 107 } 108 if (matcher == null && matchEnd - matchStart == 1) { 109 return string.subSequence(matchStart, matchEnd); 111 } 112 if (n > matcher.groupCount()) { 113 return null; 114 } 115 return matcher.group(n); 116 } 117 118 public CharSequence preMatch() { 119 if (matched()) { 120 return string.subSequence(0, matchStart); 121 } else { 122 return null; 123 } 124 } 125 126 public CharSequence postMatch() { 127 if (matched()) { 128 return string.subSequence(matchEnd, string.length()); 129 } else { 130 return null; 131 } 132 } 133 134 public CharSequence matchedValue() { 135 if (matched()) { 136 return string.subSequence(matchStart, matchEnd); 137 } else { 138 return null; 139 } 140 } 141 142 public int matchedSize() { 143 if (matcher == null) { 144 return -1; 145 } else { 146 return matchEnd - matchStart; 147 } 148 } 149 150 public void unscan() { 151 if (lastPos != -1) { 152 pos = lastPos; 153 resetMatchData(); 154 } else { 155 throw new IllegalStateException ("unscan() cannot be called after an unmached scan."); 156 } 157 } 158 159 public int matches(Pattern pattern) { 160 if (!isEndOfString()) { 161 matcher = pattern.matcher(string.subSequence(pos, string.length())); 162 if (matcher.lookingAt()) { 163 matchStart = pos; 164 matchEnd = matcher.end(); 165 return matchEnd; 166 } else { 167 resetMatchData(); 168 } 169 } 170 171 return -1; 172 } 173 174 public CharSequence scanUntil(Pattern pattern) { 175 if (!isEndOfString()) { 176 matcher = pattern.matcher(string); 177 if (matcher.find(pos)) { 178 lastPos = pos; 179 matchStart = matcher.start(); 180 matchEnd = matcher.end(); 181 pos = matchEnd; 182 return string.subSequence(lastPos, pos); 183 } else { 184 lastPos = -1; 185 resetMatchData(); 186 } 187 } 188 189 return null; 190 } 191 192 public CharSequence scan(Pattern pattern) { 193 if (!isEndOfString()) { 194 matcher = pattern.matcher(string.subSequence(pos, string.length())); 195 if (matcher.lookingAt()) { 196 lastPos = pos; 197 matchStart = pos; 198 pos += matcher.end(); 199 matchEnd = pos; 200 return matcher.group(); 201 } else { 202 lastPos = -1; 203 resetMatchData(); 204 } 205 } 206 207 return null; 208 } 209 210 public CharSequence check(Pattern pattern) { 211 if (!isEndOfString()) { 212 matcher = pattern.matcher(string.subSequence(pos, string.length())); 213 if (matcher.lookingAt()) { 214 matchStart = pos; 215 matchEnd = matchStart + matcher.end(); 216 return matcher.group(); 217 } else { 218 resetMatchData(); 219 } 220 } 221 222 return null; 223 } 224 225 public CharSequence checkUntil(Pattern pattern) { 226 if (!isEndOfString()) { 227 matcher = pattern.matcher(string); 228 if (matcher.find(pos)) { 229 matchStart = matcher.start(); 230 matchEnd = matcher.end(); 231 return string.subSequence(pos, matcher.end()); 232 } else { 233 resetMatchData(); 234 } 235 } 236 237 return null; 238 } 239 240 public int skip(Pattern pattern) { 241 if (!isEndOfString()) { 242 matcher = pattern.matcher(string.subSequence(pos, string.length())); 243 if (matcher.lookingAt()) { 244 lastPos = pos; 245 matchStart = pos; 246 int end = matcher.end(); 247 pos += end; 248 matchEnd = pos; 249 return end; 250 } else { 251 resetMatchData(); 252 } 253 } 254 255 return -1; 256 } 257 258 public int skipUntil(Pattern pattern) { 259 if (!isEndOfString()) { 260 matcher = pattern.matcher(string); 261 if (matcher.find(pos)) { 262 lastPos = pos; 263 pos = matcher.end(); 264 matchStart = matcher.start(); 265 matchEnd = pos; 266 return pos - lastPos; 267 } else { 268 resetMatchData(); 269 } 270 } 271 272 return -1; 273 } 274 275 public int exists(Pattern pattern) { 276 if (!isEndOfString()) { 277 matcher = pattern.matcher(string); 278 if (matcher.find(pos)) { 279 matchStart = matcher.start(); 280 matchEnd = matcher.end(); 281 return matchEnd - pos; 282 } else { 283 resetMatchData(); 284 } 285 } 286 287 return -1; 288 } 289 290 public CharSequence peek(int length) { 291 int end = pos + length; 292 if (end > string.length()) { 293 end = string.length(); 294 } 295 return string.subSequence(pos, end); 296 } 297 } | Popular Tags |