diff -Naur migrate_plus.orig/src/Plugin/migrate/process/PregReplace.php migrate_plus/src/Plugin/migrate/process/PregReplace.php
--- migrate_plus.orig/src/Plugin/migrate/process/PregReplace.php	1969-12-31 21:00:00.000000000 -0300
+++ migrate_plus/src/Plugin/migrate/process/PregReplace.php	2017-07-20 21:44:05.000000000 -0300
@@ -0,0 +1,98 @@
+<?php
+
+namespace Drupal\migrate_plus\Plugin\migrate\process;
+
+use Drupal\migrate\ProcessPluginBase;
+use Drupal\migrate\MigrateExecutableInterface;
+use Drupal\migrate\Row;
+
+/**
+ * Perform a regular expression search and replace, matches can be modified by
+ * other plugins.
+ *
+ * Examples:
+ *
+ * Consider a node migration, where you want replace entity reference
+ * placeholders, where the entity id needs to be looked up in previous
+ * migrations.
+ *
+ * @code
+ * plugin: preg_replace
+ *   source: post_content
+ *   pattern: '#\[nggallery id="?(\d+)"?\]#i'
+ *   replacement_pattern: '<drupal-entity data-entity-type="node"
+ *     data-entity-id="preg_replace_placeholder_1" />'
+ *   process:
+ *     preg_replace_placeholder_1:
+ *       plugin: migration_lookup
+ *       migration: drv_gallery
+ *       no_stub: true
+ *       source: 'preg_replace_match_1'
+ * @endcode
+ *
+ * This searches for wordpress next gen gallery tags in an imput string and
+ * replaces them with the corresponding entity_embed tag, the entity id from a
+ * previous migration will be looked up by the migration_lookup plugin using the
+ * source id in the captured sub-pattern.
+ *
+ * Regular expressions without sub-patterns will get replaced directly by the
+ * replacement_pattern.
+ *
+ * @see \Drupal\migrate\Plugin\MigrateProcessInterface
+ *
+ * @MigrateProcessPlugin(
+ *   id = "preg_replace"
+ * )
+ */
+class PregReplace extends ProcessPluginBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
+
+    $limit = isset($this->configuration['limit']) ? $this->configuration['limit'] : -1;
+
+    $value = preg_replace_callback(
+      $this->configuration['pattern'],
+      function ($matches) use ($migrate_executable, $row, $destination_property) {
+        // If there are no captured (parenthesized) sub-pattern, than just replace
+        // the whole pattern with the replacement_pattern.
+        if (!isset($matches[1])) {
+          return $this->configuration['replacement_pattern'];
+        }
+
+        // Matches from captured sub-patterns will be passed as value to
+        // the iterator plugin.
+        $new_value = [];
+        foreach ($matches as $delta => $match) {
+          // skip element 0, as it contain the text that matched the full pattern.
+          if (0 == $delta) {
+            continue;
+          }
+          $new_value['preg_replace_match_' . $delta] = $match;
+        }
+
+        $new_row = new Row($new_value, []);
+        $process = $this->configuration['process'];
+        if ($process) {
+          $migrate_executable->processRow($new_row, $this->configuration['process']);
+        }
+        $destination = $new_row->getDestination();
+
+        // Replace destination placeholders in replacement pattern.
+        $return = str_replace(array_keys($destination), $destination, $this->configuration['replacement_pattern']);
+
+        // Replace source placeholders in replacement pattern.
+        $return = str_replace(array_keys($new_value), $new_value, $return);
+
+        return $return;
+      },
+      $value,
+      $limit
+    );
+
+    return $value;
+  }
+
+}
