diff --git a/xpdf-3.03/xpdf/PDFCore.cc b/xpdf-3.03-mine/xpdf/PDFCore.cc
index 6435815..2c0beff 100644
--- a/xpdf-3.03/xpdf/PDFCore.cc
+++ b/xpdf-3.03-mine/xpdf/PDFCore.cc
@@ -1654,22 +1654,151 @@ GString *PDFCore::extractText(int pg, double xMin, double yMin,
 }
 
 GBool PDFCore::find(char *s, GBool caseSensitive, GBool next, GBool backward,
-		    GBool wholeWord, GBool onePageOnly) {
-  Unicode *u;
-  int len, i;
+		    GBool wholeWord, GBool onePageOnly, GBool useRegEx) {
   GBool ret;
+  if (!useRegEx){
+    Unicode *u;
+    int len, i;
+    
+    // convert to Unicode
+    len = (int)strlen(s);
+    u = (Unicode *)gmallocn(len, sizeof(Unicode));
+    for (i = 0; i < len; ++i) {
+      u[i] = (Unicode)(s[i] & 0xff);
+    }
+    ret = findU(u, len, caseSensitive, next, backward, wholeWord, onePageOnly);
+    gfree(u);
+  } else {
+    ret = findRegEx(s, caseSensitive, next, backward, onePageOnly);
+  }
+  return ret;
+}
+
+GBool PDFCore::findRegEx(char *s, GBool caseSensitive, GBool next,
+			 GBool backward, GBool onePageOnly) {
+  TextOutputDev *textOut;
+  double xMin, yMin, xMax, yMax;
+  PDFCorePage *page;
+  PDFCoreTile *tile;
+  int pg, len;
+  GBool startAtTop, startAtLast, stopAtLast;
 
-  // convert to Unicode
-  len = (int)strlen(s);
-  u = (Unicode *)gmallocn(len, sizeof(Unicode));
-  for (i = 0; i < len; ++i) {
-    u[i] = (Unicode)(s[i] & 0xff);
+  // check for zero-length string
+  len = strlen(s);
+  if (len == 0) {
+    return gFalse;
   }
 
-  ret = findU(u, len, caseSensitive, next, backward, wholeWord, onePageOnly);
+  setBusyCursor(gTrue);
 
-  gfree(u);
-  return ret;
+  // search current page starting at previous result, current
+  // selection, or top/bottom of page
+  startAtTop = startAtLast = gFalse;
+  xMin = yMin = xMax = yMax = 0;
+  pg = topPage;
+  if (next) {
+    startAtLast = gTrue;
+  } else if (selectULX != selectLRX && selectULY != selectLRY) {
+    pg = selectPage;
+    if (backward) {
+      xMin = selectULX - 1;
+      yMin = selectULY - 1;
+    } else {
+      xMin = selectULX + 1;
+      yMin = selectULY + 1;
+    }
+  } else {
+    startAtTop = gTrue;
+  }
+  if (!(page = findPage(pg))) {
+    displayPage(pg, zoom, rotate, gTrue, gFalse);
+    page = findPage(pg);
+  }
+  if (page->text->findRegEx(s, startAtTop, gTrue, startAtLast, gFalse,
+			    caseSensitive, backward,
+			    &xMin, &yMin, &xMax, &yMax)) {
+    goto found;
+  }
+
+  if (!onePageOnly) {
+
+    // search following/previous pages
+    textOut = new TextOutputDev(NULL, gTrue, 0, gFalse, gFalse);
+    if (!textOut->isOk()) {
+      delete textOut;
+      goto notFound;
+    }
+    for (pg = backward ? pg - 1 : pg + 1;
+	 backward ? pg >= 1 : pg <= doc->getNumPages();
+	 pg += backward ? -1 : 1) {
+      doc->displayPage(textOut, pg, 72, 72, 0, gFalse, gTrue, gFalse);
+      if (textOut->findRegEx(s, gTrue, gTrue, gFalse, gFalse,
+			     caseSensitive, backward,
+			     &xMin, &yMin, &xMax, &yMax)) {
+	delete textOut;
+	goto foundPage;
+      }
+    }
+
+    // search previous/following pages
+    for (pg = backward ? doc->getNumPages() : 1;
+	 backward ? pg > topPage : pg < topPage;
+	 pg += backward ? -1 : 1) {
+      doc->displayPage(textOut, pg, 72, 72, 0, gFalse, gTrue, gFalse);
+      if (textOut->findRegEx(s, gTrue, gTrue, gFalse, gFalse,
+			     caseSensitive, backward,
+			     &xMin, &yMin, &xMax, &yMax)) {
+	delete textOut;
+	goto foundPage;
+      }
+    }
+    delete textOut;
+
+  }
+
+  // search current page ending at previous result, current selection,
+  // or bottom/top of page
+  if (!startAtTop) {
+    xMin = yMin = xMax = yMax = 0;
+    if (next) {
+      stopAtLast = gTrue;
+    } else {
+      stopAtLast = gFalse;
+      xMax = selectLRX;
+      yMax = selectLRY;
+    }
+    if (page->text->findRegEx(s, gTrue, gFalse, gFalse, stopAtLast,
+			      caseSensitive, backward,
+			      &xMin, &yMin, &xMax, &yMax)) {
+      goto found;
+    }
+  }
+
+  // not found
+ notFound:
+  setBusyCursor(gFalse);
+  return gFalse;
+
+  // found on a different page
+ foundPage:
+  update(pg, scrollX, continuousMode ? -1 : 0, zoom, rotate, gFalse, gTrue,
+	 gTrue);
+  page = findPage(pg);
+  if (!page->text->findRegEx(s, gTrue, gTrue, gFalse, gFalse,
+			     caseSensitive, backward,
+			     &xMin, &yMin, &xMax, &yMax)) {
+    // this can happen if coalescing is bad
+    goto notFound;
+  }
+
+  // found: change the selection
+ found:
+  tile = (PDFCoreTile *)page->tiles->get(0);
+  setSelection(pg, (int)floor(xMin), (int)floor(yMin),
+	       (int)ceil(xMax), (int)ceil(yMax));
+
+  setBusyCursor(gFalse);
+  return gTrue;
 }
 
 GBool PDFCore::findU(Unicode *u, int len, GBool caseSensitive,
diff --git a/xpdf-3.03/xpdf/PDFCore.h b/xpdf-3.03-mine/xpdf/PDFCore.h
index 264756f..2b34b67 100644
--- a/xpdf-3.03/xpdf/PDFCore.h
+++ b/xpdf-3.03-mine/xpdf/PDFCore.h
@@ -211,7 +211,9 @@ public:
   //----- find
 
   virtual GBool find(char *s, GBool caseSensitive, GBool next, GBool backward,
-		     GBool wholeWord, GBool onePageOnly);
+		     GBool wholeWord, GBool onePageOnly, GBool useRegEx);
+  virtual GBool findRegEx(char *s, GBool caseSensitive, GBool next,
+			  GBool backward, GBool onePageOnly);
   virtual GBool findU(Unicode *u, int len, GBool caseSensitive,
 		      GBool next, GBool backward, GBool wholeWord,
 		      GBool onePageOnly);
diff --git a/xpdf-3.03/xpdf/TextOutputDev.cc b/xpdf-3.03-mine/xpdf/TextOutputDev.cc
index 971a3fe..933ab79 100644
--- a/xpdf-3.03/xpdf/TextOutputDev.cc
+++ b/xpdf-3.03-mine/xpdf/TextOutputDev.cc
@@ -17,6 +17,7 @@
 #include <stddef.h>
 #include <math.h>
 #include <ctype.h>
+#include <regex.h>
 #ifdef WIN32
 #include <fcntl.h> // for O_BINARY
 #include <io.h>    // for setmode
@@ -3337,6 +3338,211 @@ GBool TextPage::findText(Unicode *s, int len,
   return gFalse;
 }
 
+GBool TextPage::findRegEx(char *s,
+			 GBool startAtTop, GBool stopAtBottom,
+			 GBool startAtLast, GBool stopAtLast,
+			 GBool caseSensitive, GBool backward,
+			 double *xMin, double *yMin,
+			 double *xMax, double *yMax) {
+  TextBlock *blk;
+  TextLine *line;
+  char *txt;
+  int txtSize, m, i;
+  double xStart, yStart, xStop, yStop;
+  double xMin0, yMin0, xMax0, yMax0;
+  double xMin1, yMin1, xMax1, yMax1;
+  GBool found;
+
+  //~ needs to handle right-to-left text
+
+  if (rawOrder) {
+    return gFalse;
+  }
+
+  regex_t re;
+  int code;
+  code = regcomp(&re, s, caseSensitive ? 0 : REG_ICASE);
+  if(code){
+    size_t errorStringLength;
+    char *errorString;
+    errorStringLength = regerror(code , &re, (char *)NULL, (size_t)0);
+    errorString = (char*)malloc(errorStringLength*sizeof(char));
+    regerror(code , &re, errorString, errorStringLength);
+    fprintf(stderr, "regcomp error %d: %s\n", code, errorString);
+    free(errorString);
+    return gFalse;
+  }
+  
+  txt = NULL;
+  txtSize = 0;
+
+  xStart = yStart = xStop = yStop = 0;
+  if (startAtLast && haveLastFind) {
+    xStart = lastFindXMin;
+    yStart = lastFindYMin;
+  } else if (!startAtTop) {
+    xStart = *xMin;
+    yStart = *yMin;
+  }
+  if (stopAtLast && haveLastFind) {
+    xStop = lastFindXMin;
+    yStop = lastFindYMin;
+  } else if (!stopAtBottom) {
+    xStop = *xMax;
+    yStop = *yMax;
+  }
+
+  found = gFalse;
+  xMin0 = xMax0 = yMin0 = yMax0 = 0; // make gcc happy
+  xMin1 = xMax1 = yMin1 = yMax1 = 0; // make gcc happy
+
+  for (i = backward ? nBlocks - 1 : 0;
+       backward ? i >= 0 : i < nBlocks;
+       i += backward ? -1 : 1) {
+    blk = blocks[i];
+
+    // check: is the block above the top limit?
+    // (this only works if the page's primary rotation is zero --
+    // otherwise the blocks won't be sorted in the useful order)
+    if (!startAtTop && primaryRot == 0 &&
+	(backward ? blk->yMin > yStart : blk->yMax < yStart)) {
+      continue;
+    }
+
+    // check: is the block below the bottom limit?
+    // (this only works if the page's primary rotation is zero --
+    // otherwise the blocks won't be sorted in the useful order)
+    if (!stopAtBottom && primaryRot == 0 &&
+	(backward ? blk->yMax < yStop : blk->yMin > yStop)) {
+      break;
+    }
+
+    for (line = blk->lines; line; line = line->next) {
+
+      // check: is the line above the top limit?
+      // (this only works if the page's primary rotation is zero --
+      // otherwise the lines won't be sorted in the useful order)
+      if (!startAtTop && primaryRot == 0 &&
+	  (backward ? line->yMin > yStart : line->yMin < yStart)) {
+	continue;
+      }
+
+      // check: is the line below the bottom limit?
+      // (this only works if the page's primary rotation is zero --
+      // otherwise the lines won't be sorted in the useful order)
+      if (!stopAtBottom && primaryRot == 0 &&
+	  (backward ? line->yMin < yStop : line->yMin > yStop)) {
+	continue;
+      }
+
+      // convert the line to ASCII
+      m = line->len;
+      if (m > txtSize) {
+	txt = (char *)greallocn(txt, m+1, sizeof(char));
+	txtSize = m;
+      }
+      txt[m] = '\0';
+      Unicode *textLine = line->text;
+      for (int j = 0; j < m; ++j) {
+	if ( textLine[j] == (textLine[j] & 0xff) )
+	  txt[j] = (char)textLine[j];
+	else
+	  txt[j] = '?';
+      }
+
+      // search each position in this line
+      regmatch_t match;
+      regoff_t offset = 0;
+      code = 0;
+      while(REG_NOMATCH != code) {
+	code = regexec(&re, txt+(int)offset*sizeof(char), 1, &match, 0);
+	if(!code) {
+	  // found it
+#if 0 // for debugging
+	  int k;
+	  printf("%s\n", txt);
+	  for(k=0; k<match.rm_so+offset;k++) printf(" ");
+	  for(k=offset; k<match.rm_eo-match.rm_so+offset;k++) printf("^");
+	  printf("\n");
+#endif
+	  switch (line->rot) {
+	  case 0:
+ 	    xMin1 = line->edge[match.rm_so+offset];
+ 	    xMax1 = line->edge[match.rm_eo+offset];
+	    yMin1 = line->yMin;
+	    yMax1 = line->yMax;
+	    break;
+	  case 1:
+	    xMin1 = line->xMin;
+	    xMax1 = line->xMax;
+	    yMin1 = line->edge[match.rm_so+offset];
+	    yMax1 = line->edge[match.rm_eo+offset];
+	    break;
+	  case 2:
+	    xMin1 = line->edge[match.rm_eo+offset];
+	    xMax1 = line->edge[match.rm_so+offset];
+	    yMin1 = line->yMin;
+	    yMax1 = line->yMax;
+	    break;
+	  case 3:
+	    xMin1 = line->xMin;
+	    xMax1 = line->xMax;
+	    yMin1 = line->edge[match.rm_eo+offset];
+	    yMax1 = line->edge[match.rm_so+offset];
+	    break;
+	  }
+	  if (backward) {
+	    if ((startAtTop ||
+		 yMin1 < yStart || (yMin1 == yStart && xMin1 < xStart)) &&
+		(stopAtBottom ||
+		 yMin1 > yStop || (yMin1 == yStop && xMin1 > xStop))) {
+	      if (!found ||
+		  yMin1 > yMin0 || (yMin1 == yMin0 && xMin1 > xMin0)) {
+		xMin0 = xMin1;
+		xMax0 = xMax1;
+		yMin0 = yMin1;
+		yMax0 = yMax1;
+		found = gTrue;
+	      }
+	    }
+	  } else {
+	    if ((startAtTop ||
+		 yMin1 > yStart || (yMin1 == yStart && xMin1 > xStart)) &&
+		(stopAtBottom ||
+		 yMin1 < yStop || (yMin1 == yStop && xMin1 < xStop))) {
+	      if (!found ||
+		  yMin1 < yMin0 || (yMin1 == yMin0 && xMin1 < xMin0)) {
+		xMin0 = xMin1;
+		xMax0 = xMax1;
+		yMin0 = yMin1;
+		yMax0 = yMax1;
+		found = gTrue;
+	      }
+	    }
+	  }
+	}
+	offset += match.rm_eo;
+      }
+    }
+  }
+
+  regfree(&re);
+  gfree(txt);
+
+  if (found) {
+    *xMin = xMin0;
+    *xMax = xMax0;
+    *yMin = yMin0;
+    *yMax = yMax0;
+    lastFindXMin = xMin0;
+    lastFindYMin = yMin0;
+    haveLastFind = gTrue;
+    return gTrue;
+  }
+
+  return gFalse;
+}
+
 GString *TextPage::getText(double xMin, double yMin,
 			   double xMax, double yMax) {
   GString *s;
@@ -4304,6 +4510,18 @@ GBool TextOutputDev::findText(Unicode *s, int len,
 			xMin, yMin, xMax, yMax);
 }
 
+GBool TextOutputDev::findRegEx(char *s,
+			      GBool startAtTop, GBool stopAtBottom,
+			      GBool startAtLast, GBool stopAtLast,
+			      GBool caseSensitive, GBool backward,
+			      double *xMin, double *yMin,
+			      double *xMax, double *yMax) {
+  return text->findRegEx(s, startAtTop, stopAtBottom,
+			 startAtLast, stopAtLast,
+			 caseSensitive, backward,
+			 xMin, yMin, xMax, yMax);
+}
+
 GString *TextOutputDev::getText(double xMin, double yMin,
 				double xMax, double yMax) {
   return text->getText(xMin, yMin, xMax, yMax);
diff --git a/xpdf-3.03/xpdf/TextOutputDev.h b/xpdf-3.03-mine/xpdf/TextOutputDev.h
index e3bb26c..2fbf635 100644
--- a/xpdf-3.03/xpdf/TextOutputDev.h
+++ b/xpdf-3.03-mine/xpdf/TextOutputDev.h
@@ -469,6 +469,13 @@ public:
 		 double *xMin, double *yMin,
 		 double *xMax, double *yMax);
 
+  GBool findRegEx(char *s,
+		 GBool startAtTop, GBool stopAtBottom,
+		 GBool startAtLast, GBool stopAtLast,
+		 GBool caseSensitive, GBool backward,
+		 double *xMin, double *yMin,
+		 double *xMax, double *yMax);
+
   // Get the text which is inside the specified rectangle.
   GString *getText(double xMin, double yMin,
 		   double xMax, double yMax);
@@ -649,6 +656,13 @@ public:
 		 double *xMin, double *yMin,
 		 double *xMax, double *yMax);
 
+  GBool findRegEx(char *s,
+		 GBool startAtTop, GBool stopAtBottom,
+		 GBool startAtLast, GBool stopAtLast,
+		 GBool caseSensitive, GBool backward,
+		 double *xMin, double *yMin,
+		 double *xMax, double *yMax);
+
   // Get the text which is inside the specified rectangle.
   GString *getText(double xMin, double yMin,
 		   double xMax, double yMax);
diff --git a/xpdf-3.03/xpdf/XPDFCore.cc b/xpdf-3.03-mine/xpdf/XPDFCore.cc
index b98bc37..22c8f4c 100644
--- a/xpdf-3.03/xpdf/XPDFCore.cc
+++ b/xpdf-3.03-mine/xpdf/XPDFCore.cc
@@ -721,9 +721,10 @@ GString *XPDFCore::mungeURL(GString *url) {
 //------------------------------------------------------------------------
 
 GBool XPDFCore::find(char *s, GBool caseSensitive, GBool next,
-		     GBool backward, GBool wholeWord, GBool onePageOnly) {
+		     GBool backward, GBool wholeWord, GBool onePageOnly,
+		     GBool useRegEx) {
   if (!PDFCore::find(s, caseSensitive, next,
-		     backward, wholeWord, onePageOnly)) {
+		     backward, wholeWord, onePageOnly, useRegEx)) {
     XBell(display, 0);
     return gFalse;
   }
diff --git a/xpdf-3.03/xpdf/XPDFCore.h b/xpdf-3.03-mine/xpdf/XPDFCore.h
index be1dcfa..cb7af37 100644
--- a/xpdf-3.03/xpdf/XPDFCore.h
+++ b/xpdf-3.03-mine/xpdf/XPDFCore.h
@@ -108,7 +108,8 @@ public:
   //----- find
 
   virtual GBool find(char *s, GBool caseSensitive, GBool next,
-		     GBool backward, GBool wholeWord, GBool onePageOnly);
+		     GBool backward, GBool wholeWord, GBool onePageOnly,
+		     GBool useRegEx);
   virtual GBool findU(Unicode *u, int len, GBool caseSensitive,
 		      GBool next, GBool backward,
 		      GBool wholeWord, GBool onePageOnly);
diff --git a/xpdf-3.03/xpdf/XPDFViewer.cc b/xpdf-3.03-mine/xpdf/XPDFViewer.cc
index 09134d3..d39fef0 100644
--- a/xpdf-3.03/xpdf/XPDFViewer.cc
+++ b/xpdf-3.03-mine/xpdf/XPDFViewer.cc
@@ -3141,7 +3141,7 @@ void XPDFViewer::findFindCbk(Widget widget, XtPointer ptr,
 			     XtPointer callData) {
   XPDFViewer *viewer = (XPDFViewer *)ptr;
 
-  viewer->doFind(gFalse);
+  viewer->doFind(gTrue);
 }
 
 void XPDFViewer::mapFindDialog() {
@@ -3160,7 +3160,8 @@ void XPDFViewer::doFind(GBool next) {
 	     next,
 	     XmToggleButtonGetState(findBackwardToggle),
 	     XmToggleButtonGetState(findWholeWordToggle),
-	     gFalse);
+	     gFalse,
+	     gTrue);
   if (XtWindow(findDialog)) {
     XUndefineCursor(display, XtWindow(findDialog));
   }
