diff --git a/core/lib/Drupal/Core/Entity/Element/EntityAutocomplete.php b/core/lib/Drupal/Core/Entity/Element/EntityAutocomplete.php
index 51adf91b7bb32522ef24cbba21cff2ad3e38fb86..9c3e705bd3744755faab7b2cefa540c9994cb2d6 100644
--- a/core/lib/Drupal/Core/Entity/Element/EntityAutocomplete.php
+++ b/core/lib/Drupal/Core/Entity/Element/EntityAutocomplete.php
@@ -348,13 +348,10 @@ public static function getEntityLabels(array $entities) {
   public static function extractEntityIdFromAutocompleteInput($input) {
     $match = NULL;
 
-    // Take "label (entity id)', match the ID from parenthesis when it's a
-    // number.
-    if (preg_match("/.+\s\((\d+)\)/", $input, $matches)) {
-      $match = $matches[1];
-    }
-    // Match the ID when it's a string (e.g. for config entity types).
-    elseif (preg_match("/.+\s\(([\w.]+)\)/", $input, $matches)) {
+    // Take "label (entity id)', match the ID from inside the parentheses.
+    // @todo Add support for entities containing parentheses in their ID.
+    // @see https://www.drupal.org/node/2520416
+    if (preg_match("/.+\s\(([^\)]+)\)/", $input, $matches)) {
       $match = $matches[1];
     }
 
diff --git a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestStringId.php b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestStringId.php
index a63abada07daccddea9c3c935d4b086ef80ee87f..342cbb9b1662e340fa16a61e1f86470a2935f50c 100644
--- a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestStringId.php
+++ b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestStringId.php
@@ -25,7 +25,8 @@
  *   entity_keys = {
  *     "id" = "id",
  *     "uuid" = "uuid",
- *     "bundle" = "type"
+ *     "bundle" = "type",
+ *     "label" = "name",
  *   },
  *   links = {
  *     "canonical" = "/entity_test_string_id/manage/{entity_test_string_id}",
diff --git a/core/tests/Drupal/KernelTests/Core/Entity/Element/EntityAutocompleteElementFormTest.php b/core/tests/Drupal/KernelTests/Core/Entity/Element/EntityAutocompleteElementFormTest.php
index ec81f7b38f8ec4f8a786145475539c7ca2c99fe4..c2d737bfb8d840e9577fc8ce1db6732dd4c3b7d2 100644
--- a/core/tests/Drupal/KernelTests/Core/Entity/Element/EntityAutocompleteElementFormTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Entity/Element/EntityAutocompleteElementFormTest.php
@@ -8,6 +8,7 @@
 use Drupal\Core\Form\FormState;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\entity_test\Entity\EntityTest;
+use Drupal\entity_test\Entity\EntityTestStringId;
 use Drupal\KernelTests\Core\Entity\EntityKernelTestBase;
 use Drupal\user\Entity\User;
 
@@ -46,6 +47,7 @@ protected function setUp() {
     parent::setUp();
 
     $this->installSchema('system', ['key_value_expire']);
+    $this->installEntitySchema('entity_test_string_id');
     \Drupal::service('router.builder')->rebuild();
 
     $this->testUser = User::create(array(
@@ -68,6 +70,17 @@ protected function setUp() {
       $entity->save();
       $this->referencedEntities[] = $entity;
     }
+
+    // Use special characters in the ID of some of the test entities so we can
+    // test if these are handled correctly.
+    for ($i = 0; $i < 2; $i++) {
+      $entity = EntityTestStringId::create([
+        'name' => $this->randomMachineName(),
+        'id' => $this->randomMachineName() . '&</\\:?',
+      ]);
+      $entity->save();
+      $this->referencedEntities[] = $entity;
+    }
   }
 
   /**
@@ -150,6 +163,16 @@ public function buildForm(array $form, FormStateInterface $form_state) {
       '#default_value' => array($this->referencedEntities[0], $this->referencedEntities[1]),
     );
 
+    $form['single_string_id'] = array(
+      '#type' => 'entity_autocomplete',
+      '#target_type' => 'entity_test_string_id',
+    );
+    $form['tags_string_id'] = array(
+      '#type' => 'entity_autocomplete',
+      '#target_type' => 'entity_test_string_id',
+      '#tags' => TRUE,
+    );
+
     return $form;
   }
 
@@ -181,6 +204,8 @@ public function testValidEntityAutocompleteElement() {
           $this->getAutocompleteInput($this->referencedEntities[0])
           . ', tags - autocreated entity label with specific uid, '
           . $this->getAutocompleteInput($this->referencedEntities[1]),
+        'single_string_id' => $this->getAutocompleteInput($this->referencedEntities[2]),
+        'tags_string_id' => $this->getAutocompleteInput($this->referencedEntities[2]) . ', ' . $this->getAutocompleteInput($this->referencedEntities[3]),
       ]);
     $form_builder = $this->container->get('form_builder');
     $form_builder->submitForm($this, $form_state);
@@ -231,6 +256,16 @@ public function testValidEntityAutocompleteElement() {
     $this->assertEqual($value[1]['entity']->getOwnerId(), $this->testAutocreateUser->id());
     // Third value is an existing entity.
     $this->assertEqual($value[2]['target_id'], $this->referencedEntities[1]->id());
+
+    // Test the 'single_string_id' element.
+    $this->assertEquals($this->referencedEntities[2]->id(), $form_state->getValue('single_string_id'));
+
+    // Test the 'tags_string_id' element.
+    $expected = [
+      ['target_id' => $this->referencedEntities[2]->id()],
+      ['target_id' => $this->referencedEntities[3]->id()],
+    ];
+    $this->assertEquals($expected, $form_state->getValue('tags_string_id'));
   }
 
   /**