blob: 40858cc1dbb317ce413b045744fcce0923628ba3 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 1995-2004 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26package sun.misc;
27
28/**
29 * A class to represent a regular expression. Only handles '*'s.
30 * @author James Gosling
31 */
32
33public class Regexp {
34 /** if true then the matching process ignores case. */
35 public boolean ignoreCase;
36
37 /*
38 * regular expressions are carved into three regions: a constant string
39 * prefix, a constant string suffix, and a series of floating strings in
40 * between. In the input regular expression, they are separated by *s
41 */
42 public String exp;
43 public String prefix, suffix;
44 public boolean exact;
45 public int prefixLen, suffixLen, totalLen;
46 public String mids[];
47
48 /** Create a new regular expression object. The regular expression
49 is a series of constant strings separated by *s. For example:
50 <dl>
51 <dt>*.gif <dd>Matches any string that ends in ".gif".
52 <dt>/tmp/* <dd>Matches any string that starts with "/tmp/".
53 <dt>/tmp/*.gif <dd>Matches any string that starts with "/tmp/" and ends
54 with ".gif".
55 <dt>/tmp/*new*.gif <dd>Matches any string that starts with "/tmp/"
56 and ends with ".gif" and has "new" somewhere in between.
57 </dl>
58 */
59 public Regexp (String s) {
60 exp = s;
61 int firstst = s.indexOf('*');
62 int lastst = s.lastIndexOf('*');
63 if (firstst < 0) {
64 totalLen = s.length();
65 exact = true; // no * s
66 } else {
67 prefixLen = firstst;
68 if (firstst == 0)
69 prefix = null;
70 else
71 prefix = s.substring(0, firstst);
72 suffixLen = s.length() - lastst - 1;
73 if (suffixLen == 0)
74 suffix = null;
75 else
76 suffix = s.substring(lastst + 1);
77 int nmids = 0;
78 int pos = firstst;
79 while (pos < lastst && pos >= 0) {
80 nmids++;
81 pos = s.indexOf('*', pos + 1);
82 }
83 totalLen = prefixLen + suffixLen;
84 if (nmids > 0) {
85 mids = new String[nmids];
86 pos = firstst;
87 for (int i = 0; i < nmids; i++) {
88 pos++;
89 int npos = s.indexOf('*', pos);
90 if (pos < npos) {
91 mids[i] = s.substring(pos, npos);
92 totalLen += mids[i].length();
93 }
94 pos = npos;
95 }
96 }
97 }
98 }
99
100 /** Returns true iff the String s matches this regular expression. */
101 final boolean matches(String s) {
102 return matches(s, 0, s.length());
103 }
104
105 /** Returns true iff the substring of s from offset for len characters
106 matches this regular expression. */
107 boolean matches(String s, int offset, int len) {
108 if (exact)
109 return len == totalLen &&
110 exp.regionMatches(ignoreCase, 0, s, offset, len);
111 if (len < totalLen)
112 return false;
113 if (prefixLen > 0 &&
114 !prefix.regionMatches(ignoreCase,
115 0, s, offset, prefixLen)
116 ||
117 suffixLen > 0 &&
118 !suffix.regionMatches(ignoreCase,
119 0, s, offset + len - suffixLen,
120 suffixLen))
121 return false;
122 if (mids == null)
123 return true;
124 int nmids = mids.length;
125 int spos = offset + prefixLen;
126 int limit = offset+len-suffixLen;
127 for (int i = 0; i<nmids; i++) {
128 String ms = mids[i];
129 int ml = ms.length();
130 while (spos+ml<=limit &&
131 !ms.regionMatches(ignoreCase,
132 0, s, spos, ml))
133 spos++;
134 if (spos+ml>limit)
135 return false;
136 spos+=ml;
137 }
138 return true;
139 }
140
141}