diff --git a/token.module b/token.module
index 4a89077..09b041a 100644
--- a/token.module
+++ b/token.module
@@ -630,40 +630,51 @@ function token_get_invalid_tokens_by_context($value, $valid_types = array(), $le
     $valid_tokens += $tokens;
   }
 
   foreach ($value_tokens as $token) {
     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] . '?'])) {
         continue;
       }
     }
     $invalid_tokens[] = $token;
   }
 
   array_unique($invalid_tokens);
+
+  // Some modules use wildcard suffixes like _? or -???? or -*.
+  if (!empty($invalid_tokens)) {
+    foreach (array_keys($valid_tokens) as $token) {
+      if (preg_match('/^(.*[_-])[?*]+$/', $token, $wildcards)) {
+        $matched = preg_grep('/^' . $wildcards[1] . '.+$/', $invalid_tokens);
+        $invalid_tokens = array_diff($invalid_tokens, $matched);
+      }
+    }
+  }
+
   $invalid_tokens = token_prepare_tokens($invalid_tokens, $leading, $trailing);
   return $invalid_tokens;
 }
 
 /**
  * Build a list of all token-like patterns that appear in the text.
  *
  * @param $text
  *   The text to be scanned for possible tokens.
  * @param $leading
  *   Character(s) to prepend to the token key before searching for
  *   matches. Defaults to TOKEN_PREFIX.
  * @param $trailing
  *   Character(s) to append to the token key before searching for
  *   matches. Defaults to TOKEN_SUFFIX.
  *
  * @return
  *   An array of discovered tokens.
  */
 function token_scan($text, $leading = TOKEN_PREFIX, $trailing = TOKEN_SUFFIX) {
