diff --git a/core/includes/token.inc b/core/includes/token.inc
index 7a5fea1..a147b25 100644
--- a/core/includes/token.inc
+++ b/core/includes/token.inc
@@ -77,8 +77,13 @@
  *   Text with tokens replaced.
  */
 function token_replace($text, array $data = array(), array $options = array()) {
+  $text_tokens = token_scan($text);
+  if (empty($text_tokens)) {
+    return $text;
+  }
+
   $replacements = array();
-  foreach (token_scan($text) as $type => $tokens) {
+  foreach ($text_tokens as $type => $tokens) {
     $replacements += token_generate($type, $tokens, $data, $options);
     if (!empty($options['clear'])) {
       $replacements += array_fill_keys($tokens, '');
diff --git a/core/modules/system/system.test b/core/modules/system/system.test
index 4e3761d..9ffefc8 100644
--- a/core/modules/system/system.test
+++ b/core/modules/system/system.test
@@ -1865,6 +1865,9 @@ class TokenReplaceTestCase extends DrupalWebTestCase {
 
     $generated = token_generate('node', $raw_tokens, array('node' => $node), array('sanitize' => FALSE));
     $this->assertEqual($generated['[node:title]'], $node->title, t('Unsanitized token generated properly.'));
+
+    // Test token replacement when the string contains no tokens.
+    $this->assertEqual(token_replace('No tokens here.'), 'No tokens here.');
   }
 
   /**
