Source for java.util.regex.Matcher

   1: /* Matcher.java -- Instance of a regular expression applied to a char sequence.
   2:    Copyright (C) 2002, 2004, 2006 Free Software Foundation, Inc.
   3: 
   4: This file is part of GNU Classpath.
   5: 
   6: GNU Classpath is free software; you can redistribute it and/or modify
   7: it under the terms of the GNU General Public License as published by
   8: the Free Software Foundation; either version 2, or (at your option)
   9: any later version.
  10: 
  11: GNU Classpath is distributed in the hope that it will be useful, but
  12: WITHOUT ANY WARRANTY; without even the implied warranty of
  13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14: General Public License for more details.
  15: 
  16: You should have received a copy of the GNU General Public License
  17: along with GNU Classpath; see the file COPYING.  If not, write to the
  18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  19: 02110-1301 USA.
  20: 
  21: Linking this library statically or dynamically with other modules is
  22: making a combined work based on this library.  Thus, the terms and
  23: conditions of the GNU General Public License cover the whole
  24: combination.
  25: 
  26: As a special exception, the copyright holders of this library give you
  27: permission to link this library with independent modules to produce an
  28: executable, regardless of the license terms of these independent
  29: modules, and to copy and distribute the resulting executable under
  30: terms of your choice, provided that you also meet, for each linked
  31: independent module, the terms and conditions of the license of that
  32: module.  An independent module is a module which is not derived from
  33: or based on this library.  If you modify this library, you may extend
  34: this exception to your version of the library, but you are not
  35: obligated to do so.  If you do not wish to do so, delete this
  36: exception statement from your version. */
  37: 
  38: 
  39: package java.util.regex;
  40: 
  41: import gnu.regexp.RE;
  42: import gnu.regexp.REMatch;
  43: 
  44: /**
  45:  * Instance of a regular expression applied to a char sequence.
  46:  *
  47:  * @since 1.4
  48:  */
  49: public final class Matcher implements MatchResult
  50: {
  51:   private Pattern pattern;
  52:   private CharSequence input;
  53:   private int position;
  54:   private int appendPosition;
  55:   private REMatch match;
  56: 
  57:   Matcher(Pattern pattern, CharSequence input)
  58:   {
  59:     this.pattern = pattern;
  60:     this.input = input;
  61:   }
  62:   
  63:   /**
  64:    * @param sb The target string buffer
  65:    * @param replacement The replacement string
  66:    *
  67:    * @exception IllegalStateException If no match has yet been attempted,
  68:    * or if the previous match operation failed
  69:    * @exception IndexOutOfBoundsException If the replacement string refers
  70:    * to a capturing group that does not exist in the pattern
  71:    */
  72:   public Matcher appendReplacement (StringBuffer sb, String replacement)
  73:     throws IllegalStateException
  74:   {
  75:     assertMatchOp();
  76:     sb.append(input.subSequence(appendPosition,
  77:                 match.getStartIndex()).toString());
  78:     sb.append(match.substituteInto(replacement));
  79:     appendPosition = match.getEndIndex();
  80:     return this;
  81:   }
  82: 
  83:   /**
  84:    * @param sb The target string buffer
  85:    */
  86:   public StringBuffer appendTail (StringBuffer sb)
  87:   {
  88:     sb.append(input.subSequence(appendPosition, input.length()).toString());
  89:     return sb;
  90:   }
  91:  
  92:   /**
  93:    * @exception IllegalStateException If no match has yet been attempted,
  94:    * or if the previous match operation failed
  95:    */
  96:   public int end ()
  97:     throws IllegalStateException
  98:   {
  99:     assertMatchOp();
 100:     return match.getEndIndex();
 101:   }
 102:   
 103:   /**
 104:    * @param group The index of a capturing group in this matcher's pattern
 105:    *
 106:    * @exception IllegalStateException If no match has yet been attempted,
 107:    * or if the previous match operation failed
 108:    * @exception IndexOutOfBoundsException If the replacement string refers
 109:    * to a capturing group that does not exist in the pattern
 110:    */
 111:   public int end (int group)
 112:     throws IllegalStateException
 113:   {
 114:     assertMatchOp();
 115:     return match.getEndIndex(group);
 116:   }
 117:  
 118:   public boolean find ()
 119:   {
 120:     boolean first = (match == null);
 121:     match = pattern.getRE().getMatch(input, position);
 122:     if (match != null)
 123:       {
 124:     int endIndex = match.getEndIndex();
 125:     // Are we stuck at the same position?
 126:     if (!first && endIndex == position)
 127:       {
 128:         match = null;
 129:         // Not at the end of the input yet?
 130:         if (position < input.length() - 1)
 131:           {
 132:         position++;
 133:         return find(position);
 134:           }
 135:         else
 136:           return false;
 137:       }
 138:     position = endIndex;
 139:     return true;
 140:       }
 141:     return false;
 142:   } 
 143: 
 144:   /**
 145:    * @param start The index to start the new pattern matching
 146:    *
 147:    * @exception IndexOutOfBoundsException If the replacement string refers
 148:    * to a capturing group that does not exist in the pattern
 149:    */
 150:   public boolean find (int start)
 151:   {
 152:     match = pattern.getRE().getMatch(input, start);
 153:     if (match != null)
 154:       {
 155:     position = match.getEndIndex();
 156:     return true;
 157:       }
 158:     return false;
 159:   }
 160:  
 161:   /**
 162:    * @exception IllegalStateException If no match has yet been attempted,
 163:    * or if the previous match operation failed
 164:    */
 165:   public String group ()
 166:   {
 167:     assertMatchOp();
 168:     return match.toString();
 169:   }
 170:   
 171:   /**
 172:    * @param group The index of a capturing group in this matcher's pattern
 173:    *
 174:    * @exception IllegalStateException If no match has yet been attempted,
 175:    * or if the previous match operation failed
 176:    * @exception IndexOutOfBoundsException If the replacement string refers
 177:    * to a capturing group that does not exist in the pattern
 178:    */
 179:   public String group (int group)
 180:     throws IllegalStateException
 181:   {
 182:     assertMatchOp();
 183:     return match.toString(group);
 184:   }
 185: 
 186:   /**
 187:    * @param replacement The replacement string
 188:    */
 189:   public String replaceFirst (String replacement)
 190:   {
 191:     reset();
 192:     // Semantics might not quite match
 193:     return pattern.getRE().substitute(input, replacement, position);
 194:   }
 195: 
 196:   /**
 197:    * @param replacement The replacement string
 198:    */
 199:   public String replaceAll (String replacement)
 200:   {
 201:     reset();
 202:     return pattern.getRE().substituteAll(input, replacement, position);
 203:   }
 204:   
 205:   public int groupCount ()
 206:   {
 207:     return pattern.getRE().getNumSubs();
 208:   }
 209:  
 210:   public boolean lookingAt ()
 211:   {
 212:     match = pattern.getRE().getMatch(input, 0);
 213:     if (match != null)
 214:       {
 215:     if (match.getStartIndex() == 0)
 216:       {
 217:         position = match.getEndIndex();
 218:         return true;
 219:       }
 220:     match = null;
 221:       }
 222:     return false;
 223:   }
 224:   
 225:   /**
 226:    * Attempts to match the entire input sequence against the pattern. 
 227:    *
 228:    * If the match succeeds then more information can be obtained via the
 229:    * start, end, and group methods.
 230:    *
 231:    * @see #start()
 232:    * @see #end()
 233:    * @see #group()
 234:    */
 235:   public boolean matches ()
 236:   {
 237:     match = pattern.getRE().getMatch(input, 0, RE.REG_TRY_ENTIRE_MATCH);
 238:     if (match != null)
 239:       {
 240:     if (match.getStartIndex() == 0)
 241:       {
 242:         position = match.getEndIndex();
 243:         if (position == input.length())
 244:             return true;
 245:       }
 246:     match = null;
 247:       }
 248:     return false;
 249:   }
 250:   
 251:   /**
 252:    * Returns the Pattern that is interpreted by this Matcher
 253:    */
 254:   public Pattern pattern ()
 255:   {
 256:     return pattern;
 257:   }
 258:   
 259:   public Matcher reset ()
 260:   {
 261:     position = 0;
 262:     match = null;
 263:     return this;
 264:   }
 265:   
 266:   /**
 267:    * @param input The new input character sequence
 268:    */
 269:   public Matcher reset (CharSequence input)
 270:   {
 271:     this.input = input;
 272:     return reset();
 273:   }
 274:   
 275:   /**
 276:    * @returns the index of a capturing group in this matcher's pattern
 277:    *
 278:    * @exception IllegalStateException If no match has yet been attempted,
 279:    * or if the previous match operation failed
 280:    */
 281:   public int start ()
 282:     throws IllegalStateException
 283:   {
 284:     assertMatchOp();
 285:     return match.getStartIndex();
 286:   }
 287: 
 288:   /**
 289:    * @param group The index of a capturing group in this matcher's pattern
 290:    *
 291:    * @exception IllegalStateException If no match has yet been attempted,
 292:    * or if the previous match operation failed
 293:    * @exception IndexOutOfBoundsException If the replacement string refers
 294:    * to a capturing group that does not exist in the pattern
 295:    */
 296:   public int start (int group)
 297:     throws IllegalStateException
 298:   {
 299:     assertMatchOp();
 300:     return match.getStartIndex(group);
 301:   }
 302: 
 303:   private void assertMatchOp()
 304:   {
 305:     if (match == null) throw new IllegalStateException();
 306:   }
 307: }