// // This software is now distributed according to // the Lesser Gnu Public License. Please see // http://www.gnu.org/copyleft/lesser.txt for // the details. // -- Happy Computing! // package com.stevesoft.pat; import java.io.*; import java.util.*; /** * This class is a different form of Regex designed to work more like the file * matching utility of a Unix shell. It is implemented by some simple string * transformations:
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
FileRegex Regex
* .*
. \.
{ (?:
{?! (?!
{?= (?=
{?? (??
} )
? .
{,} (|)
Note that a FileRegex pattern always ends with the Regex * pattern element "$". If you like to experiment, try making FileRegex's and * then printing them out. The toString() method does a decompile of the pattern * to a standard Regex. Here are some more complete examples:
* * * * * * * * * * * * *
FileRegex Regex
*.java .*\.java$
*.{java,html} .*\.(java|html)$
foo.[chC] foo.[chC]$
*/ public class FileRegex extends Regex { // /** Build an unitialized FileRegex. */ // public FileRegex() // { // dirflag = EITHER; // } // // /** Build a FileRegex form String s. */ // public FileRegex(String s) // { // super(s); // dirflag = EITHER; // } // // /** // * Compile a new pattern. Throws // * // * @exception com.stevesoft.pat.RegSyntax // * for nonsensical patterns like "[9-0]+" just as Regex // * does. // * @see com.stevesoft.pat#compile(java.lang.String) // */ // public void compile(String s) throws RegSyntax // { // String npat = toFileRegex(s); // super.compile(npat); // if (File.separatorChar == '\\') // MS-DOS // { // ignoreCase = true; // } // } // // /** // * This is the method required by FileNameFilter. To get a listing of files in // * the current directory ending in .java, do this: // * // *
//   * File dot = new File(".");
//   * 
//   * FileRegex java_files = new FileRegex("*.java");
//   * 
//   * String[] file_list = dot.list(java_files);
//   * 
// */ // public boolean accept(File dir, String s) // { // if (dirflag != EITHER) // { // File f = new File(s); // if (f.isDirectory() && dirflag == NONDIR) // { // return false; // } // if (!f.isDirectory() && dirflag == DIR) // { // return false; // } // } // return matchAt(s, 0); // } // // int dirflag = 0; // // final static int EITHER = 0, DIR = 1, NONDIR = 2; // // /** // * Provides an alternative to File.list -- this separates its argument // * according to File.pathSeparator. To each path, it splits off a directory -- // * all characters up to and including the first instance of File.separator -- // * and a file pattern -- the part that comes after the directory. It then // * produces a list of all the pattern matches on all the paths. Thus // * "*.java:../*.java" would produce a list of all the java files in this // * directory and in the ".." directory on a Unix machine. "*.java;..\\*.java" // * would do the same thing on a Dos machine. // */ // public static String[] list(String f) // { // return list(f, EITHER); // } // // static String[] list(String f, int df) // { // // return list_(f,new FileRegex()); // StringTokenizer st = new StringTokenizer(f, File.pathSeparator); // Vector v = new Vector(); // while (st.hasMoreTokens()) // { // String path = st.nextToken(); // list1(path, v, df, true); // } // String[] sa = new String[v.size()]; // v.copyInto(sa); // return sa; // } // // final static Regex root = new Regex(File.separatorChar == '/' ? "/$" // : "(?:.:|)\\\\$"); // // static void list1(String path, Vector v, int df, boolean rec) // { // // if path looks like a/b/c/ or d:\ then add . // if (root.matchAt(path, 0)) // { // v.addElement(path + "."); // return; // } // File f = new File(path); // if (f.getParent() != null && rec) // { // Vector v2 = new Vector(); // list1(f.getParent(), v2, DIR, true); // for (int i = 0; i < v2.size(); i++) // { // String path2 = ((String) v2.elementAt(i)) + File.separator // + f.getName(); // list1(path2, v, df, false); // } // } // else // { // File base = new File(path); // // String dir_s = base.getParent(); // if (dir_s == null) // { // dir_s = "."; // } // File dir = new File(dir_s); // // FileRegex fr = new FileRegex(base.getName()); // if (fr.isLiteral()) // { // v.addElement(dir_s + File.separator + base.getName()); // return; // } // fr.dirflag = df; // String[] sa = dir.list(fr); // if (sa == null) // { // return; // } // for (int i = 0; i < sa.length; i++) // { // v.addElement(dir_s + File.separator + sa[i]); // } // } // } // // /** // * This method takes a file regular expression, and translates it into the // * type of pattern used by a normal Regex. // */ // public static String toFileRegex(String s) // { // StrPos sp = new StrPos(s, 0); // StringBuffer sb = new StringBuffer(); // if (sp.incMatch("{?e=")) // { // char e = sp.thisChar(); // sp.inc(); // if (sp.incMatch("}")) // { // sb.append("(?e=" + e + ")^"); // } // else // { // sb.append("^(?e="); // } // sp.esc = e; // } // int ParenLvl = 0; // while (!sp.eos()) // { // if (File.separatorChar == '\\') // { // if (sp.escaped()) // { // sb.append("\\\\"); // } // sp.dontMatch = false; // } // if (sp.incMatch("?")) // { // sb.append("."); // } // else if (sp.incMatch(".")) // { // sb.append(sp.esc); // sb.append('.'); // } // else if (sp.incMatch("{??")) // { // sb.append("(??"); // ParenLvl++; // // allow negative lookahead to work // } // else if (sp.incMatch("{?!")) // { // sb.append("(?!"); // ParenLvl++; // // allow positive lookahead to work // } // else if (sp.incMatch("{?=")) // { // sb.append("(?="); // ParenLvl++; // } // else if (sp.incMatch("{")) // { // sb.append("(?:"); // ParenLvl++; // } // else if (sp.incMatch("}")) // { // sb.append(')'); // ParenLvl--; // } // else if (ParenLvl != 0 && sp.incMatch(",")) // { // sb.append('|'); // } // else if (sp.incMatch("*")) // { // sb.append(".*"); // } // else // { // sb.append(sp.thisChar()); // sp.inc(); // } // } // sb.append("$"); // return sb.toString(); // } // // public boolean isLiteral() // { // Pattern x = thePattern; // while (x != null && !(x instanceof End)) // { // if (x instanceof oneChar) // { // ; // } // else if (x instanceof Skipped) // { // ; // } // else // { // return false; // } // x = x.next; // } // return true; // } }