home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1995 November / PCWK1195.iso / inne / win95 / sieciowe / hotja32.lzh / hotjava / classsrc / java / util / regexp.java < prev    next >
Text File  |  1995-08-11  |  6KB  |  189 lines

  1. /*
  2.  * @(#)Regexp.java    1.1 95/04/01
  3.  * 
  4.  * Copyright (c) 1995 Sun Microsystems, Inc.  All Rights reserved Permission to
  5.  * use, copy, modify, and distribute this software and its documentation for
  6.  * NON-COMMERCIAL purposes and without fee is hereby granted provided that
  7.  * this copyright notice appears in all copies. Please refer to the file
  8.  * copyright.html for further important copyright and licensing information.
  9.  * 
  10.  * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
  11.  * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  12.  * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
  13.  * OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY
  14.  * LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR
  15.  * ITS DERIVATIVES.
  16.  */
  17.  
  18. package java.util;
  19.  
  20. /**
  21.  * A class to represent a regular expression.  Only handles '*'s.
  22.  * @author  James Gosling
  23.  */
  24.  
  25. public class Regexp {
  26.     /** if true then the matching process ignores case. */
  27.     public boolean ignoreCase;
  28.  
  29.     /*
  30.      * regular expressions are carved into three regions: a constant string
  31.      * prefix, a constant string suffix, and a series of floating strings in
  32.      * between.  In the input regular expression, they are seperated by *s
  33.      */
  34.     public String exp;
  35.     public String prefix, suffix;
  36.     public boolean exact;
  37.     public int prefixLen, suffixLen, totalLen;
  38.     public String mids[];
  39.  
  40.     /** Create a new regular expression object.  The regular expression
  41.         is a series of constant strings seperated by *s.  For example:
  42.         <dl>
  43.         <dt>*.gif       <dd>Matches any string that ends in ".gif".
  44.         <dt>/tmp/*      <dd>Matches any string that starts with "/tmp/".
  45.         <dt>/tmp/*.gif  <dd>Matches any string that starts with "/tmp/" and ends
  46.                         with ".gif".
  47.         <dt>/tmp/*new*.gif <dd>Matches any string that starts with "/tmp/"
  48.                         and ends with ".gif" and has "new" somewhere in between.
  49.         </dl>
  50.      */
  51.     public Regexp (String s) {
  52.         exp = s;
  53.     int firstst = s.indexOf('*');
  54.     int lastst = s.lastIndexOf('*');
  55.     if (firstst < 0) {
  56.         totalLen = s.length();
  57.         exact = true;    // no * s
  58.     } else {
  59.         prefixLen = firstst;
  60.         if (firstst == 0)
  61.         prefix = null;
  62.         else
  63.         prefix = s.substring(0, firstst);
  64.         suffixLen = s.length() - lastst - 1;
  65.         if (suffixLen == 0)
  66.         suffix = null;
  67.         else
  68.         suffix = s.substring(lastst + 1);
  69.         int nmids = 0;
  70.         int pos = firstst;
  71.         while (pos < lastst && pos >= 0) {
  72.         nmids++;
  73.         pos = s.indexOf('*', pos + 1);
  74.         }
  75.         totalLen = prefixLen + suffixLen;
  76.         if (nmids > 0) {
  77.         mids = new String[nmids];
  78.         pos = firstst;
  79.         for (int i = 0; i < nmids; i++) {
  80.             pos++;
  81.             int npos = s.indexOf('*', pos);
  82.             if (pos < npos) {
  83.             mids[i] = s.substring(pos, npos);
  84.             totalLen += mids[i].length();
  85.             }
  86.             pos = npos;
  87.         }
  88.         }
  89.     }
  90.     }
  91.  
  92.     /** Returns true iff the String s matches this regular expression. */
  93.     final boolean matches(String s) {
  94.     return matches(s, 0, s.length());
  95.     }
  96.  
  97.     /** Returns true iff the substring of s from offset for len characters
  98.         matches this regular expression. */
  99.     boolean matches(String s, int offset, int len) {
  100.     if (exact)
  101.         return len == totalLen &&
  102.         exp.regionMatches(ignoreCase, 0, s, offset, len);
  103.     if (len < totalLen)
  104.         return false;
  105.     if (prefixLen > 0 &&
  106.         !prefix.regionMatches(ignoreCase,
  107.                       0, s, offset, prefixLen)
  108.         ||
  109.         suffixLen > 0 &&
  110.         !suffix.regionMatches(ignoreCase,
  111.                       0, s, offset + len - suffixLen,
  112.                       suffixLen))
  113.         return false;
  114.         if (mids == null)
  115.             return true;
  116.         int nmids = mids.length;
  117.     int spos = offset + prefixLen;
  118.         int limit = offset+len-suffixLen;
  119.         for (int i = 0; i<nmids; i++) {
  120.             String ms = mids[i];
  121.             int ml = ms.length();
  122.             while (spos+ml<=limit &&
  123.                    !ms.regionMatches(ignoreCase,
  124.                                      0, s, spos, ml))
  125.                 spos++;
  126.             if (spos+ml>limit)
  127.                 return false;
  128.             spos+=ml;
  129.         }
  130.         return true;
  131.     }
  132.  
  133.     /** Returns subst with *s replaced by those regions of s that
  134.         matched the *s in the regular expression.  This assumes that
  135.         s matches this regular expression.  For example, given the
  136.         regular expression "/tmp/*.ras" which matches "/tmp/foo.ras"
  137.         invoking re.substitute("/tmp/foo.ras","/dir/*.gif") returns
  138.         "/dir/foo.gif" */
  139.     String substitute(String s, String subst) {
  140.     if (exact)
  141.         return subst;
  142.         if (mids == null) {
  143.             /* Just one */
  144.             int star = subst.indexOf('*');
  145.             if (star < 0)
  146.                 return subst;
  147.             return subst.substring(0, star)+
  148.             s.substring(prefixLen, s.length()-suffixLen)+
  149.             subst.substring(star+1);
  150.         }
  151.     if (len < totalLen)
  152.         return false;
  153.     if (prefixLen > 0 &&
  154.         !prefix.regionMatches(ignoreCase,
  155.                       0, s, offset, prefixLen)
  156.         ||
  157.         suffixLen > 0 &&
  158.         !suffix.regionMatches(ignoreCase,
  159.                       0, s, offset + len - suffixLen,
  160.                       suffixLen))
  161.         return false;
  162.         if (mids == null)
  163.             return true;
  164.         int nmids = mids.length;
  165.     int spos = offset + prefixLen;
  166.         int limit = offset+len-suffixLen;
  167.         for (int i = 0; i<nmids; i++) {
  168.             String ms = mids[i];
  169.             int ml = ms.length();
  170.             while (spos+ml<=limit &&
  171.                    !ms.regionMatches(ignoreCase,
  172.                                      0, s, spos, ml))
  173.                 spos++;
  174.             if (spos+ml>limit)
  175.                 return false;
  176.             spos+=ml;
  177.         }
  178.         return true;
  179.     }
  180.  
  181.     static public void main(String argv[]) {
  182.         Regexp r = new Regexp(argv[0]);
  183.         System.out.print("re="+r+"\n");
  184.         r.ignoreCase = true;
  185.         for (int i = 1; i<argv.length; i++)
  186.             System.out.print("<"+argv[i]+"> "+r.matches(argv[i])+"\n");
  187.     }
  188. }
  189.