Source for java.util.regex.Matcher

   1: /* Matcher.java -- Instance of a regular expression applied to a char sequence.
   2:    Copyright (C) 2002, 2004 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.REMatch;
  42: 
  43: /**
  44:  * Instance of a regular expression applied to a char sequence.
  45:  *
  46:  * @since 1.4
  47:  */
  48: public final class Matcher
  49: {
  50:   private Pattern pattern;
  51:   private CharSequence input;
  52:   private int position;
  53:   private int appendPosition;
  54:   private REMatch match;
  55: 
  56:   Matcher(Pattern pattern, CharSequence input)
  57:   {
  58:     this.pattern = pattern;
  59:     this.input = input;
  60:   }
  61:   
  62:   /**
  63:    * @param sb The target string buffer
  64:    * @param replacement The replacement string
  65:    *
  66:    * @exception IllegalStateException If no match has yet been attempted,
  67:    * or if the previous match operation failed
  68:    * @exception IndexOutOfBoundsException If the replacement string refers
  69:    * to a capturing group that does not exist in the pattern
  70:    */
  71:   public Matcher appendReplacement (StringBuffer sb, String replacement)
  72:     throws IllegalStateException
  73:   {
  74:     assertMatchOp();
  75:     sb.append(input.subSequence(appendPosition,
  76:                 match.getStartIndex()).toString());
  77:     sb.append(match.substituteInto(replacement));
  78:     appendPosition = match.getEndIndex();
  79:     return this;
  80:   }
  81: 
  82:   /**
  83:    * @param sb The target string buffer
  84:    */
  85:   public StringBuffer appendTail (StringBuffer sb)
  86:   {
  87:     sb.append(input.subSequence(appendPosition, input.length()).toString());
  88:     return sb;
  89:   }
  90:  
  91:   /**
  92:    * @exception IllegalStateException If no match has yet been attempted,
  93:    * or if the previous match operation failed
  94:    */
  95:   public int end ()
  96:     throws IllegalStateException
  97:   {
  98:     assertMatchOp();
  99:     return match.getEndIndex();
 100:   }
 101:   
 102:   /**
 103:    * @param group The index of a capturing group in this matcher's pattern
 104:    *
 105:    * @exception IllegalStateException If no match has yet been attempted,
 106:    * or if the previous match operation failed
 107:    * @exception IndexOutOfBoundsException If the replacement string refers
 108:    * to a capturing group that does not exist in the pattern
 109:    */
 110:   public int end (int group)
 111:     throws IllegalStateException
 112:   {
 113:     assertMatchOp();
 114:     return match.getEndIndex(group);
 115:   }
 116:  
 117:   public boolean find ()
 118:   {
 119:     boolean first = (match == null);
 120:     match = pattern.getRE().getMatch(input, position);
 121:     if (match != null)
 122:       {
 123:     int endIndex = match.getEndIndex();
 124:     // Are we stuck at the same position?
 125:     if (!first && endIndex == position)
 126:       {
 127:         match = null;
 128:         // Not at the end of the input yet?
 129:         if (position < input.length() - 1)
 130:           {
 131:         position++;
 132:         return find(position);
 133:           }
 134:         else
 135:           return false;
 136:       }
 137:     position = endIndex;
 138:     return true;
 139:       }
 140:     return false;
 141:   } 
 142: 
 143:   /**
 144:    * @param start The index to start the new pattern matching
 145:    *
 146:    * @exception IndexOutOfBoundsException If the replacement string refers
 147:    * to a capturing group that does not exist in the pattern
 148:    */
 149:   public boolean find (int start)
 150:   {
 151:     match = pattern.getRE().getMatch(input, start);
 152:     if (match != null)
 153:       {
 154:     position = match.getEndIndex();
 155:     return true;
 156:       }
 157:     return false;
 158:   }
 159:  
 160:   /**
 161:    * @exception IllegalStateException If no match has yet been attempted,
 162:    * or if the previous match operation failed
 163:    */
 164:   public String group ()
 165:   {
 166:     assertMatchOp();
 167:     return match.toString();
 168:   }
 169:   
 170:   /**
 171:    * @param group The index of a capturing group in this matcher's pattern
 172:    *
 173:    * @exception IllegalStateException If no match has yet been attempted,
 174:    * or if the previous match operation failed
 175:    * @exception IndexOutOfBoundsException If the replacement string refers
 176:    * to a capturing group that does not exist in the pattern
 177:    */
 178:   public String group (int group)
 179:     throws IllegalStateException
 180:   {
 181:     assertMatchOp();
 182:     return match.toString(group);
 183:   }
 184: 
 185:   /**
 186:    * @param replacement The replacement string
 187:    */
 188:   public String replaceFirst (String replacement)
 189:   {
 190:     reset();
 191:     // Semantics might not quite match
 192:     return pattern.getRE().substitute(input, replacement, position);
 193:   }
 194: 
 195:   /**
 196:    * @param replacement The replacement string
 197:    */
 198:   public String replaceAll (String replacement)
 199:   {
 200:     reset();
 201:     return pattern.getRE().substituteAll(input, replacement, position);
 202:   }
 203:   
 204:   public int groupCount ()
 205:   {
 206:     return pattern.getRE().getNumSubs();
 207:   }
 208:  
 209:   public boolean lookingAt ()
 210:   {
 211:     match = pattern.getRE().getMatch(input, 0);
 212:     if (match != null)
 213:       {
 214:     if (match.getStartIndex() == 0)
 215:       {
 216:         position = match.getEndIndex();
 217:         return true;
 218:       }
 219:     match = null;
 220:       }
 221:     return false;
 222:   }
 223:   
 224:   /**
 225:    * Attempts to match the entire input sequence against the pattern. 
 226:    *
 227:    * If the match succeeds then more information can be obtained via the
 228:    * start, end, and group methods.
 229:    *
 230:    * @see #start()
 231:    * @see #end()
 232:    * @see #group()
 233:    */
 234:   public boolean matches ()
 235:   {
 236:     if (lookingAt())
 237:       {
 238:     if (position == input.length())
 239:       return true;
 240:     match = null;
 241:       }
 242:     return false;
 243:   }
 244:   
 245:   /**
 246:    * Returns the Pattern that is interpreted by this Matcher
 247:    */
 248:   public Pattern pattern ()
 249:   {
 250:     return pattern;
 251:   }
 252:   
 253:   public Matcher reset ()
 254:   {
 255:     position = 0;
 256:     match = null;
 257:     return this;
 258:   }
 259:   
 260:   /**
 261:    * @param input The new input character sequence
 262:    */
 263:   public Matcher reset (CharSequence input)
 264:   {
 265:     this.input = input;
 266:     return reset();
 267:   }
 268:   
 269:   /**
 270:    * @returns the index of a capturing group in this matcher's pattern
 271:    *
 272:    * @exception IllegalStateException If no match has yet been attempted,
 273:    * or if the previous match operation failed
 274:    */
 275:   public int start ()
 276:     throws IllegalStateException
 277:   {
 278:     assertMatchOp();
 279:     return match.getStartIndex();
 280:   }
 281: 
 282:   /**
 283:    * @param group The index of a capturing group in this matcher's pattern
 284:    *
 285:    * @exception IllegalStateException If no match has yet been attempted,
 286:    * or if the previous match operation failed
 287:    * @exception IndexOutOfBoundsException If the replacement string refers
 288:    * to a capturing group that does not exist in the pattern
 289:    */
 290:   public int start (int group)
 291:     throws IllegalStateException
 292:   {
 293:     assertMatchOp();
 294:     return match.getStartIndex(group);
 295:   }
 296: 
 297:   private void assertMatchOp()
 298:   {
 299:     if (match == null) throw new IllegalStateException();
 300:   }
 301: }