Index: modules/analysis/common/src/test/org/apache/lucene/analysis/pattern/TestPatternReplaceCharFilter.java
===================================================================
--- modules/analysis/common/src/test/org/apache/lucene/analysis/pattern/TestPatternReplaceCharFilter.java	(revision 1292616)
+++ modules/analysis/common/src/test/org/apache/lucene/analysis/pattern/TestPatternReplaceCharFilter.java	(working copy)
@@ -21,6 +21,7 @@
 import java.io.Reader;
 import java.io.StringReader;
 import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
 
 import org.apache.lucene.analysis.Analyzer;
 import org.apache.lucene.analysis.BaseTokenStreamTestCase;
@@ -29,6 +30,7 @@
 import org.apache.lucene.analysis.MockTokenizer;
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.Tokenizer;
+import org.apache.lucene.util._TestUtil;
 
 /**
  * Tests {@link PatternReplaceCharFilter}
@@ -178,18 +180,33 @@
   
   /** blast some random strings through the analyzer */
   public void testRandomStrings() throws Exception {
-    Analyzer a = new Analyzer() {
-      @Override
-      protected TokenStreamComponents createComponents(String fieldName, Reader reader) {
-        Tokenizer tokenizer = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
-        return new TokenStreamComponents(tokenizer, tokenizer);
-      }
+    int numPatterns = atLeast(100);
+    for (int i = 0; i < numPatterns; i++) {
+      final Pattern p = randomPattern();
+      final String replacement = _TestUtil.randomUnicodeString(random);
+      Analyzer a = new Analyzer() {
+        @Override
+        protected TokenStreamComponents createComponents(String fieldName, Reader reader) {
+          Tokenizer tokenizer = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+          return new TokenStreamComponents(tokenizer, tokenizer);
+        }
 
-      @Override
-      protected Reader initReader(Reader reader) {
-        return new PatternReplaceCharFilter(Pattern.compile("a"), "b", CharReader.get(reader));
+        @Override
+        protected Reader initReader(Reader reader) {
+          return new PatternReplaceCharFilter(p, replacement, CharReader.get(reader));
+        }
+      };
+      checkRandomData(random, a, 1000*RANDOM_MULTIPLIER);
+    }
+  }
+  
+  public static Pattern randomPattern() {
+    while (true) {
+      try {
+        return Pattern.compile(_TestUtil.randomRegexpishString(random));
+      } catch (PatternSyntaxException ignored) {
+        // if at first you don't succeed...
       }
-    };
-    checkRandomData(random, a, 10000*RANDOM_MULTIPLIER);
+    }
   }
-}
+ }
Index: lucene/test-framework/src/java/org/apache/lucene/util/_TestUtil.java
===================================================================
--- lucene/test-framework/src/java/org/apache/lucene/util/_TestUtil.java	(revision 1292616)
+++ lucene/test-framework/src/java/org/apache/lucene/util/_TestUtil.java	(working copy)
@@ -249,6 +249,44 @@
     }
   }
   
+  /**
+   * Returns a String thats "regexpish" (contains lots of operators typically found in regular expressions)
+   * If you call this enough times, you might get a valid regex!
+   */
+  public static String randomRegexpishString(Random r) {
+    final int end = r.nextInt(20);
+    if (end == 0) {
+      // allow 0 length
+      return "";
+    }
+    final char[] buffer = new char[end];
+    for (int i = 0; i < end; i++) {
+      int t = r.nextInt(15);
+      if (0 == t && i < end - 1) {
+        // Make a surrogate pair
+        // High surrogate
+        buffer[i++] = (char) _TestUtil.nextInt(r, 0xd800, 0xdbff);
+        // Low surrogate
+        buffer[i] = (char) _TestUtil.nextInt(r, 0xdc00, 0xdfff);
+      }
+      else if (t <= 1) buffer[i] = (char) r.nextInt(0x80);
+      else if (2 == t) buffer[i] = (char) _TestUtil.nextInt(r, 0x80, 0x800);
+      else if (3 == t) buffer[i] = (char) _TestUtil.nextInt(r, 0x800, 0xd7ff);
+      else if (4 == t) buffer[i] = (char) _TestUtil.nextInt(r, 0xe000, 0xffff);
+      else if (5 == t) buffer[i] = '.';
+      else if (6 == t) buffer[i] = '?';
+      else if (7 == t) buffer[i] = '*';
+      else if (8 == t) buffer[i] = '+';
+      else if (9 == t) buffer[i] = '(';
+      else if (10 == t) buffer[i] = ')';
+      else if (11 == t) buffer[i] = '-';
+      else if (12 == t) buffer[i] = '[';
+      else if (13 == t) buffer[i] = ']';
+      else if (14 == t) buffer[i] = '|';
+    }
+    return new String(buffer, 0, end);
+  }
+  
   private static final String[] HTML_CHAR_ENTITIES = {
       "AElig", "Aacute", "Acirc", "Agrave", "Alpha", "AMP", "Aring", "Atilde",
       "Auml", "Beta", "COPY", "Ccedil", "Chi", "Dagger", "Delta", "ETH",
Index: lucene/test-framework/src/java/org/apache/lucene/util/automaton/AutomatonTestUtil.java
===================================================================
--- lucene/test-framework/src/java/org/apache/lucene/util/automaton/AutomatonTestUtil.java	(revision 1292616)
+++ lucene/test-framework/src/java/org/apache/lucene/util/automaton/AutomatonTestUtil.java	(working copy)
@@ -35,7 +35,7 @@
   /** Returns random string, including full unicode range. */
   public static String randomRegexp(Random r) {
     while (true) {
-      String regexp = randomRegexpString(r);
+      String regexp = _TestUtil.randomRegexpishString(r);
       // we will also generate some undefined unicode queries
       if (!UnicodeUtil.validUTF16String(regexp))
         continue;
@@ -45,40 +45,6 @@
       } catch (Exception e) {}
     }
   }
-
-  private static String randomRegexpString(Random r) {
-    final int end = r.nextInt(20);
-    if (end == 0) {
-      // allow 0 length
-      return "";
-    }
-    final char[] buffer = new char[end];
-    for (int i = 0; i < end; i++) {
-      int t = r.nextInt(15);
-      if (0 == t && i < end - 1) {
-        // Make a surrogate pair
-        // High surrogate
-        buffer[i++] = (char) _TestUtil.nextInt(r, 0xd800, 0xdbff);
-        // Low surrogate
-        buffer[i] = (char) _TestUtil.nextInt(r, 0xdc00, 0xdfff);
-      }
-      else if (t <= 1) buffer[i] = (char) r.nextInt(0x80);
-      else if (2 == t) buffer[i] = (char) _TestUtil.nextInt(r, 0x80, 0x800);
-      else if (3 == t) buffer[i] = (char) _TestUtil.nextInt(r, 0x800, 0xd7ff);
-      else if (4 == t) buffer[i] = (char) _TestUtil.nextInt(r, 0xe000, 0xffff);
-      else if (5 == t) buffer[i] = '.';
-      else if (6 == t) buffer[i] = '?';
-      else if (7 == t) buffer[i] = '*';
-      else if (8 == t) buffer[i] = '+';
-      else if (9 == t) buffer[i] = '(';
-      else if (10 == t) buffer[i] = ')';
-      else if (11 == t) buffer[i] = '-';
-      else if (12 == t) buffer[i] = '[';
-      else if (13 == t) buffer[i] = ']';
-      else if (14 == t) buffer[i] = '|';
-    }
-    return new String(buffer, 0, end);
-  }
   
   /** picks a random int code point, avoiding surrogates;
    * throws IllegalArgumentException if this transition only
