diff --git a/tests/token_test.module b/tests/token_test.module
index 210a051..d698825 100644
--- a/tests/token_test.module
+++ b/tests/token_test.module
@@ -4,7 +4,6 @@
  * Implements hook_exit().
  */
 function token_test_exit() {
-  debug($debug);
   if ($debug = variable_get('token_page_tokens', array())) {
     $debug += array('tokens' => array(), 'data' => array(), 'options' => array());
     foreach (array_keys($debug['tokens']) as $token) {
@@ -13,3 +12,40 @@ function token_test_exit() {
     variable_set('token_page_tokens', $debug);
   }
 }
+
+/**
+ * Implements hook_token_list().
+ */
+function token_test_token_list($type = 'all') {
+  $tokens = array();
+
+  if ($type == 'all' || $type == 'global') {
+    // Provide some wildcard tokens
+    $tokens['token_test']['alpha']           = t("Token test Alpha.");
+    $tokens['token_test']['beta-N']          = t("Token test Beta with wildcard.");
+    $tokens['token_test']['gamma_?']       = t("Token test Gamme with wildcard.");
+    $tokens['token_test']['delta-?']         = t("Token test Delta with wildcard.");
+    $tokens['token_test']['epsilon-zeta-?']  = t("Token test Epsilon-Zeta with wildcard.");
+  }
+
+  return $tokens;
+}
+
+/**
+ * Implements hook_token_values().
+ */
+function token_test_token_values($type, $object = NULL, $options = array()) {
+  $tokens = array();
+
+  if ($type == 'global') {
+    // Provide some wildcard token values
+    $tokens['alpha']           = 'Alpha';
+    $tokens['beta-1']          = 'Beta plus 1';
+    $tokens['beta-2']          = 'Beta plus 2';
+    $tokens['gamma_A']         = 'Gamma plus A';
+    $tokens['delta-extra']     = 'Delta plus extra';
+    $tokens['epsilon-zeta-A']  = 'Epsilon-Zeta plus A';
+  }
+
+  return $tokens;
+}
diff --git a/token.module b/token.module
index 4a89077..6d0691f 100644
--- a/token.module
+++ b/token.module
@@ -634,12 +634,11 @@ function token_get_invalid_tokens_by_context($value, $valid_types = array(), $le
     if (isset($valid_tokens[$token])) {
       continue;
     }
-    elseif (preg_match('/^(.*[_-])\d+$/', $token, $result)) {
-      // Some modules use a 'wildcard' token, e.g. Location.module defines
-      // [location-country_N] but users actually use [location-country_0].
-      // If the token has a digit on the end and there is a 'wildcard'
-      // token definition, we should allow it.
-      if (isset($valid_tokens[$result[1] . 'N']) || isset($valid_tokens[$result[1] . '?'])) {
+    elseif (preg_match('/^(.*[_-])([^-_])+$/', $token, $matches)) {
+      // Allow tokens that do not have a direct match to tokens listed in
+      // hook_token_info() to be matched against a 'wildcard' token name, such
+      // as token-name-? or token-name-N.
+      if (isset($valid_tokens[$matches[1] . '?']) || (is_numeric($matches[2]) && isset($valid_tokens[$matches[1] . 'N']))) {
         continue;
       }
     }
diff --git a/token.test b/token.test
index 78a5ce7..38cbf82 100644
--- a/token.test
+++ b/token.test
@@ -128,6 +128,30 @@ class TokenUnitTestCase extends TokenTestHelper {
       ),
       'types' => array('all'),
     );
+    $tests[] = array(
+      'valid tokens' => array(
+        '[alpha]',
+        '[beta-1]',
+        '[beta-2]',
+        '[gamma_A]',
+        '[delta-extra]',
+        '[epsilon-zeta-A]',
+      ),
+      'invalid tokens' => array(
+        '[alpha-plus]',
+        '[beta]',
+        '[beta-]',
+        '[beta_]',
+        '[beta_1]',
+        '[beta-A]',
+        '[gamma]',
+        '[gamma_]',
+        '[gamma-A]',
+        '[delta]',
+        '[epsilon-zeta-]',
+      ),
+      'types' => array('all'),
+    );
 
     foreach ($tests as $test) {
       $tokens = array_merge($test['valid tokens'], $test['invalid tokens']);
