Index: modules/proxy/proxy_util.c
===================================================================
--- modules/proxy/proxy_util.c	(revision 1589129)
+++ modules/proxy/proxy_util.c	(working copy)
@@ -1508,6 +1508,45 @@ PROXY_DECLARE(char *) ap_proxy_worker_name(apr_poo
     return apr_pstrcat(p, "unix:", worker->s->uds_path, "|", worker->s->name, NULL);
 }
 
+/*
+ * Taken from ap_strcmp_match() :
+ * Match = 0, NoMatch = 1, Abort = -1, Inval = -2
+ * Based loosely on sections of wildmat.c by Rich Salz
+ * Hmmm... shouldn't this really go component by component?
+ *
+ * Adds handling of the "\<any>" => "<any>" unescaping.
+ */
+static int ap_proxy_strcmp_ematch(const char *str, const char *expected)
+{
+    apr_size_t x, y;
+
+    for (x = 0, y = 0; expected[y]; ++y, ++x) {
+        if ((!str[x]) && (expected[y] != '*'))
+            return -1;
+        if (expected[y] == '*') {
+            while (expected[++y] == '*');
+            if (!expected[y])
+                return 0;
+            while (str[x]) {
+                int ret;
+                if ((ret = ap_proxy_strcmp_ematch(&str[x++], &expected[y])) != 1)
+                    return ret;
+            }
+            return -1;
+        }
+        else if (expected[y] != '?') {
+            if (expected[y] == '\\') {
+                /* NUL is an invalid char! */
+                if (!expected[++y])
+                    return -2;
+            }
+            if (str[x] != expected[y])
+                return 1;
+        }
+    }
+    return (str[x] != '\0');
+}
+
 PROXY_DECLARE(proxy_worker *) ap_proxy_get_worker(apr_pool_t *p,
                                                   proxy_balancer *balancer,
                                                   proxy_server_conf *conf,
@@ -1568,11 +1607,15 @@ PROXY_DECLARE(proxy_worker *) ap_proxy_get_worker(
             if ( ((worker_name_length = strlen(worker->s->name)) <= url_length)
                 && (worker_name_length >= min_match)
                 && (worker_name_length > max_match)
-                && (strncmp(url_copy, worker->s->name, worker_name_length) == 0) ) {
+                && (worker->match_name != NULL
+                    || strncmp(url_copy, worker->s->name,
+                               worker_name_length) == 0)
+                && (worker->match_name == NULL
+                    || ap_proxy_strcmp_ematch(url_copy,
+                                              worker->match_name) == 0) ) {
                 max_worker = worker;
                 max_match = worker_name_length;
             }
-
         }
     } else {
         worker = (proxy_worker *)conf->workers->elts;
@@ -1580,7 +1623,12 @@ PROXY_DECLARE(proxy_worker *) ap_proxy_get_worker(
             if ( ((worker_name_length = strlen(worker->s->name)) <= url_length)
                 && (worker_name_length >= min_match)
                 && (worker_name_length > max_match)
-                && (strncmp(url_copy, worker->s->name, worker_name_length) == 0) ) {
+                && (worker->match_name != NULL
+                    || strncmp(url_copy, worker->s->name,
+                               worker_name_length) == 0)
+                && (worker->match_name == NULL
+                    || ap_proxy_strcmp_ematch(url_copy,
+                                              worker->match_name) == 0) ) {
                 max_worker = worker;
                 max_match = worker_name_length;
             }
@@ -1721,6 +1769,76 @@ PROXY_DECLARE(char *) ap_proxy_define_worker(apr_p
     return NULL;
 }
 
+/**
+ * Turn the Proxy[Pass]Match's substitution URL (with $N) into an
+ * ap_proxy_strcmp_ematch()able one against the requested URL.
+ */
+static char *ap_proxy_escape_match_url(apr_pool_t *p,
+                                       const char *url)
+{
+    char *r, *x;
+    const char *y;
+    apr_size_t escapes;
+
+    /* Compute how many characters need to be escaped */
+    escapes = 0;
+    for (y = url; *y; ++y) {
+        if (*y == '*' || *y == '?' || *y == '\\') {
+            escapes++;
+        }
+    }
+    /* Each escaped char needs 1 extra byte ('?' --> "\?"), a trailing '*'
+     * may be appended (see below), and the final NUL.
+     */
+    r = apr_palloc(p, (y - url) + escapes + 1 + 1);
+
+    x = r;
+    escapes = 0;
+    for (y = url; *y; ++y, ++x) {
+        /* When the URL contains '$N', replace '$N' with wildcard. */
+        if (*y == '$' && apr_isdigit(*(y + 1))) {
+            *x = '*';
+            escapes++;
+            y += 1;
+            continue;
+        }
+        /* Otherwise, escape the original '*', '?' and '\\' so that they can
+         * be handled as such by ap_proxy_strcmp_ematch().
+         */
+        if (*y == '*' || *y == '?' || *y == '\\') {
+            *x++ = '\\';
+        }
+        *x = *y;
+    }
+    /* When no $N is used in the worker's URL, an implicit $1 is appended
+     * by ap_proxy_trans_match(), use '*' to stay consistent.
+     */ 
+    if (escapes == 0) {
+        *x++ = '*';
+    }
+    *x = '\0';
+
+    return r;
+}
+
+PROXY_DECLARE(char *) ap_proxy_define_match_worker(apr_pool_t *p,
+                                             proxy_worker **worker,
+                                             proxy_balancer *balancer,
+                                             proxy_server_conf *conf,
+                                             const char *url,
+                                             int do_malloc)
+{
+    char *err;
+
+    err = ap_proxy_define_worker(p, worker, balancer, conf, url, do_malloc);
+    if (err) {
+        return err;
+    }
+
+    (*worker)->match_name = ap_proxy_escape_match_url(p, (*worker)->s->name);
+    return NULL;
+}
+
 /*
  * Create an already defined worker and free up memory
  */
Index: modules/proxy/mod_proxy.c
===================================================================
--- modules/proxy/mod_proxy.c	(revision 1589129)
+++ modules/proxy/mod_proxy.c	(working copy)
@@ -1630,15 +1630,30 @@ static const char *
         new->balancer = balancer;
     }
     else {
-        proxy_worker *worker = ap_proxy_get_worker(cmd->temp_pool, NULL, conf, de_socketfy(cmd->pool, r));
+        proxy_worker *worker = ap_proxy_get_worker(cmd->temp_pool, NULL, conf, new->real);
         int reuse = 0;
         if (!worker) {
-            const char *err = ap_proxy_define_worker(cmd->pool, &worker, NULL, conf, r, 0);
+            const char *err;
+            if (use_regex) {
+                err = ap_proxy_define_match_worker(cmd->pool, &worker, NULL,
+                                                   conf, r, 0);
+            }
+            else {
+                err = ap_proxy_define_worker(cmd->pool, &worker, NULL,
+                                             conf, r, 0);
+            }
             if (err)
                 return apr_pstrcat(cmd->temp_pool, "ProxyPass ", err, NULL);
 
             PROXY_COPY_CONF_PARAMS(worker, conf);
-        } else {
+        }
+        else if ((use_regex != 0) ^ (worker->match_name != NULL)) {
+            return apr_pstrcat(cmd->temp_pool, "ProxyPass/<Proxy> and "
+                               "ProxyPassMatch/<ProxyMatch> can't be used "
+                               "altogether with the same worker name ",
+                               "(", worker->s->name, ")", NULL);
+        }
+        else {
             reuse = 1;
             ap_log_error(APLOG_MARK, APLOG_INFO, 0, cmd->server, APLOGNO(01145)
                          "Sharing worker '%s' instead of creating new worker '%s'",
@@ -2253,6 +2268,7 @@ static const char *proxysection(cmd_parms *cmd, vo
     char *word, *val;
     proxy_balancer *balancer = NULL;
     proxy_worker *worker = NULL;
+    int use_regex = 0;
 
     const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE);
     proxy_server_conf *sconf =
@@ -2291,6 +2307,7 @@ static const char *proxysection(cmd_parms *cmd, vo
         if (!r) {
             return "Regex could not be compiled";
         }
+        use_regex = 1;
     }
 
     /* initialize our config and fetch it */
@@ -2337,12 +2354,24 @@ static const char *proxysection(cmd_parms *cmd, vo
             worker = ap_proxy_get_worker(cmd->temp_pool, NULL, sconf,
                                          de_socketfy(cmd->temp_pool, (char*)conf->p));
             if (!worker) {
-                err = ap_proxy_define_worker(cmd->pool, &worker, NULL,
-                                          sconf, conf->p, 0);
+                if (use_regex) {
+                    err = ap_proxy_define_match_worker(cmd->pool, &worker, NULL,
+                                                       sconf, conf->p, 0);
+                }
+                else {
+                    err = ap_proxy_define_worker(cmd->pool, &worker, NULL,
+                                                 sconf, conf->p, 0);
+                }
                 if (err)
                     return apr_pstrcat(cmd->temp_pool, thiscmd->name,
                                        " ", err, NULL);
             }
+            else if ((use_regex != 0) ^ (worker->match_name != NULL)) {
+                return apr_pstrcat(cmd->temp_pool, "ProxyPass/<Proxy> and "
+                                   "ProxyPassMatch/<ProxyMatch> can't be used "
+                                   "altogether with the same worker name ",
+                                   "(", worker->s->name, ")", NULL);
+            }
         }
         if (worker == NULL && balancer == NULL) {
             return apr_pstrcat(cmd->pool, thiscmd->name,
Index: modules/proxy/mod_proxy.h
===================================================================
--- modules/proxy/mod_proxy.h	(revision 1589129)
+++ modules/proxy/mod_proxy.h	(working copy)
@@ -411,6 +411,7 @@ struct proxy_worker {
     proxy_balancer  *balancer;  /* which balancer am I in? */
     apr_thread_mutex_t  *tmutex; /* Thread lock for updating address cache */
     void            *context;   /* general purpose storage */
+    char            *match_name; /* name for ap_strcmp_match()ing */
 };
 
 /*
@@ -645,6 +646,24 @@ PROXY_DECLARE(char *) ap_proxy_define_worker(apr_p
                                              int do_malloc);
 
 /**
+ * Define and Allocate space for the ap_strcmp_match()able worker to proxy
+ * configuration.
+ * @param p         memory pool to allocate worker from
+ * @param worker    the new worker
+ * @param balancer  the balancer that the worker belongs to
+ * @param conf      current proxy server configuration
+ * @param url       url containing worker name (produces match pattern)
+ * @param do_malloc true if shared struct should be malloced
+ * @return          error message or NULL if successful (*worker is new worker)
+ */
+PROXY_DECLARE(char *) ap_proxy_define_match_worker(apr_pool_t *p,
+                                             proxy_worker **worker,
+                                             proxy_balancer *balancer,
+                                             proxy_server_conf *conf,
+                                             const char *url,
+                                             int do_malloc);
+
+/**
  * Share a defined proxy worker via shm
  * @param worker  worker to be shared
  * @param shm     location of shared info
