diff --git a/src/OpenFOAM/primitives/Lists/stringListOps.H b/src/OpenFOAM/primitives/Lists/stringListOps.H
index 1da5f272b98e28411754c68f4f2d35662499d4a5..ac35d2afe4b4a4758205c6d408ba4968ec98a9fe 100644
--- a/src/OpenFOAM/primitives/Lists/stringListOps.H
+++ b/src/OpenFOAM/primitives/Lists/stringListOps.H
@@ -38,21 +38,45 @@ SourceFiles
 
 #include "labelList.H"
 #include "stringList.H"
+#include "wordReList.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 namespace Foam
 {
 
-    //- Return list indices for the strings matching the regular expression
-    //  partial matches are optional
+    //- Return list indices for strings matching the regular expression
     template<class StringType>
     labelList findStrings
     (
         const string& regexpPattern,
-        const UList<StringType>&,
-        bool partialMatch=false
+        const UList<StringType>&
     );
+
+    //- Return list indices for strings matching the regular expression
+    template<class StringType>
+    labelList findStrings
+    (
+        const wordRe&,
+        const UList<StringType>&
+    );
+
+    //- Return list indices for strings matching one of the regular expression
+    template<class StringType>
+    labelList findStrings
+    (
+        const UList<wordRe>&,
+        const UList<StringType>&
+    );
+
+    //- Return true if string matches one of the regular expressions
+    template<class StringType>
+    bool findStrings
+    (
+        const UList<wordRe>&,
+        const StringType& str
+    );
+
 }
 
 
diff --git a/src/OpenFOAM/primitives/Lists/stringListOpsTemplates.C b/src/OpenFOAM/primitives/Lists/stringListOpsTemplates.C
index f0ed36493dc6b56d3afb6ab4283647c04525504f..9ee1fa6f0a18bb7cdbe3e1c279e08f2da8d91956 100644
--- a/src/OpenFOAM/primitives/Lists/stringListOpsTemplates.C
+++ b/src/OpenFOAM/primitives/Lists/stringListOpsTemplates.C
@@ -38,8 +38,7 @@ template<class StringType>
 labelList findStrings
 (
     const string& pattern,
-    const UList<StringType>& lst,
-    bool  partialMatch
+    const UList<StringType>& lst
 )
 {
     regExp re(pattern);
@@ -48,7 +47,7 @@ labelList findStrings
     label matchI = 0;
     forAll(lst, elemI)
     {
-        if (partialMatch ? re.search(lst[elemI]) : re.match(lst[elemI]))
+        if (re.match(lst[elemI]))
         {
             matched[matchI++] = elemI;
         }
@@ -59,6 +58,75 @@ labelList findStrings
 }
 
 
+template<class StringType>
+labelList findStrings
+(
+    const wordRe& wre,
+    const UList<StringType>& lst
+)
+{
+    labelList matched(lst.size());
+
+    label matchI = 0;
+    forAll(lst, elemI)
+    {
+        if (wre.match(lst[elemI]))
+        {
+            matched[matchI++] = elemI;
+        }
+    }
+    matched.setSize(matchI);
+
+    return matched;
+}
+
+
+template<class StringType>
+labelList findStrings
+(
+    const UList<wordRe>& wreLst,
+    const UList<StringType>& lst
+)
+{
+    labelList matched(lst.size());
+
+    label matchI = 0;
+    forAll(lst, elemI)
+    {
+        forAll(wreLst, reI)
+        {
+            if (wreLst[reI].match(lst[elemI]))
+            {
+                matched[matchI++] = elemI;
+                break;
+            }
+        }
+    }
+    matched.setSize(matchI);
+
+    return matched;
+}
+
+
+template<class StringType>
+bool findStrings
+(
+    const UList<wordRe>& wreLst,
+    const StringType& str
+)
+{
+    forAll(wreLst, reI)
+    {
+        if (wreLst[reI].match(str))
+        {
+            return true;
+        }
+    }
+    
+    return false;
+}
+
+
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 } // End namespace Foam
diff --git a/src/conversion/meshTables/boundaryRegion.C b/src/conversion/meshTables/boundaryRegion.C
index d24e6dea0f825d8a69bd5ff903ff96a525b0cbc6..73b9abcd36cd7ac263494e848a21da3fe33971ae 100644
--- a/src/conversion/meshTables/boundaryRegion.C
+++ b/src/conversion/meshTables/boundaryRegion.C
@@ -27,6 +27,7 @@ License
 #include "boundaryRegion.H"
 #include "IOMap.H"
 #include "OFstream.H"
+#include "stringListOps.H"
 
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
@@ -94,6 +95,31 @@ Foam::Map<Foam::word> Foam::boundaryRegion::names() const
 }
 
 
+Foam::Map<Foam::word> Foam::boundaryRegion::names
+(
+    const List<wordRe>& patterns
+) const
+{
+    Map<word> lookup;
+
+    forAllConstIter(Map<dictionary>, *this, iter)
+    {
+        word lookupName = iter().lookupOrDefault<word>
+        (
+            "Label",
+            "boundaryRegion_" + Foam::name(iter.key())
+        );
+
+        if (findStrings(patterns, lookupName))
+        {
+            lookup.insert(iter.key(), lookupName);
+        }
+    }    
+
+    return lookup;
+}
+
+
 Foam::Map<Foam::word> Foam::boundaryRegion::boundaryTypes() const
 {
     Map<word> lookup;
diff --git a/src/conversion/meshTables/boundaryRegion.H b/src/conversion/meshTables/boundaryRegion.H
index 471ab81fe1130b3db73880428da1c124cfcfa36a..91826b4d58cda4f0621fd15a837e3325f928b90a 100644
--- a/src/conversion/meshTables/boundaryRegion.H
+++ b/src/conversion/meshTables/boundaryRegion.H
@@ -58,6 +58,7 @@ SourceFiles
 #include "dictionary.H"
 #include "labelList.H"
 #include "wordList.H"
+#include "wordReList.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -110,6 +111,9 @@ public:
         //- Return a Map of (id => name)
         Map<word> names() const;
 
+        //- Return a Map of (id => names) selected by patterns
+        Map<word> names(const List<wordRe>& patterns) const;
+
         //- Return a Map of (id => type)
         Map<word> boundaryTypes() const;
 
diff --git a/src/conversion/meshTables/cellTable.C b/src/conversion/meshTables/cellTable.C
index e1dfc4887a07221141fcf662110431ef0e91ba64..6b3789eb02d5cf42999bb364bf2c01f320a40b04 100644
--- a/src/conversion/meshTables/cellTable.C
+++ b/src/conversion/meshTables/cellTable.C
@@ -30,6 +30,7 @@ Description
 #include "IOMap.H"
 #include "OFstream.H"
 #include "wordList.H"
+#include "stringListOps.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
@@ -166,6 +167,31 @@ Foam::Map<Foam::word> Foam::cellTable::names() const
 }
 
 
+Foam::Map<Foam::word> Foam::cellTable::names
+(
+    const List<wordRe>& patterns
+) const
+{
+    Map<word> lookup;
+
+    forAllConstIter(Map<dictionary>, *this, iter)
+    {
+        word lookupName = iter().lookupOrDefault<word>
+        (
+            "Label",
+            "cellTable_" + Foam::name(iter.key())
+        );
+
+        if (findStrings(patterns, lookupName))
+        {
+            lookup.insert(iter.key(), lookupName);
+        }
+    }
+
+    return lookup;
+}
+
+
 Foam::word Foam::cellTable::name(const label& id) const
 {
     word theName("cellTable_" + Foam::name(id));
@@ -281,7 +307,7 @@ void Foam::cellTable::setName(const label& id)
 
     if (iter == end() || !iter().found("Label"))
     {
-        setName(id, "cellTable_" + ::Foam::name(id));
+        setName(id, "cellTable_" + Foam::name(id));
     }
 }
 
@@ -491,64 +517,43 @@ void Foam::cellTable::combine(const dictionary& mapDict, labelList& tableIds)
     bool remap = false;
     labelList mapping(identity(max(this->toc()) + 1));
 
-    forAllConstIter (dictionary, mapDict, iter)
+    forAllConstIter(dictionary, mapDict, iter)
     {
-        wordList  zoneNames(iter().stream());
-        labelList zoneIndex(zoneNames.size());
+        Map<word> matches = names(wordReList(iter().stream()));
 
-        label nElem = 0;
-        forAll(zoneNames, zoneI)
-        {
-            zoneIndex[nElem] = this->findIndex(zoneNames[zoneI]);
-            if (zoneIndex[nElem] >= 0)
-            {
-                if (zoneI != nElem)
-                {
-                    zoneNames[nElem] = zoneNames[zoneI];
-                }
-                ++nElem;
-            }
-        }
-
-        zoneIndex.setSize(nElem);
-        zoneNames.setSize(nElem);
-
-        if (nElem)
+        if (matches.size())
         {
             remap = true;
             label targetId = this->findIndex(iter().keyword());
 
             Info<< "combine cellTable: " << iter().keyword();
-            if (targetId >= 0)
-            {
-                Info<< " += (";
-            }
-            else
+            if (targetId < 0)
             {
+                // re-use the first element if possible
+                targetId = min(matches.toc());
+                operator[](targetId).set("Label", iter().keyword());
+
                 Info<< " = (";
             }
-            forAll(zoneNames, zoneI)
+            else
             {
-                Info<< " " << zoneNames[zoneI];
+                Info<< " += (";
             }
-            Info<< " )" << endl;
 
-            // re-use the first element if possible
-            if (targetId < 0)
-            {
-                targetId = min(zoneIndex);
-                operator[](targetId).set("Label", iter().keyword());
-            }
 
-            forAll(zoneIndex, zoneI)
+            forAllConstIter(Map<word>, matches, matchIter)
             {
-                label idx = zoneIndex[zoneI];
+                label idx = matchIter.key();
+
                 if (idx != targetId && idx >= 0)
                 {
                     mapping[idx] = targetId;
                     this->erase(idx);
                 }
+
+                Info<< " " << matchIter();
             }
+            Info<< " )" << endl;
         }
     }
 
diff --git a/src/conversion/meshTables/cellTable.H b/src/conversion/meshTables/cellTable.H
index 18c9d39e133ad86888da3ffb173385a8d673a56a..102a134b8cc458ee91929256cf8fbf88fd44d695 100644
--- a/src/conversion/meshTables/cellTable.H
+++ b/src/conversion/meshTables/cellTable.H
@@ -65,6 +65,7 @@ SourceFiles
 #include "Map.H"
 #include "dictionary.H"
 #include "labelList.H"
+#include "wordReList.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -137,6 +138,9 @@ public:
         //- Return a Map of (id => name)
         Map<word> names() const;
 
+        //- Return a Map of (id => names) selected by patterns
+        Map<word> names(const List<wordRe>& patterns) const;
+
         //- Return a Map of (id => name) for materialType (fluid | solid | shell)
         Map<word> selectType(const word& materialType) const;
 
diff --git a/src/conversion/meshTables/remappingDict b/src/conversion/meshTables/remappingDict
new file mode 100644
index 0000000000000000000000000000000000000000..d7059d051b145d708aa06ef020d0e65fa58a5043
--- /dev/null
+++ b/src/conversion/meshTables/remappingDict
@@ -0,0 +1,38 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  dev                                   |
+|   \\  /    A nd           |                                                 |
+|    \\/     M anipulation  |                                www.OpenFOAM.org |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       dictionary;
+    location    "constant";
+    object      remapping;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+// this is a simple example of remapping cellTable and boundaryRegion entries
+// NB: can't yet combine boundaryRegions, since this reorganizes the mesh faces
+
+// rename/combine cellTable entries
+//   newName ( listOldNames );
+cellTable
+{
+    fluid ( fluid "[Ff]Luid[0-9]+" "(inlet|outlet)Region" );
+    cat1  ( CAT1 "cat1_(Back|Front|Gamma)" );
+}
+
+// rename boundary regions
+//   newName oldName;
+boundaryRegion
+{
+    inlet_4  inlet_1;
+    inlet_5  inlet_2;
+    inlet_6  inlet_3;
+}
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //