Index: src/org/openstreetmap/josm/tools/SearchCompilerQueryWizard.java
===================================================================
--- src/org/openstreetmap/josm/tools/SearchCompilerQueryWizard.java	(revision 17296)
+++ src/org/openstreetmap/josm/tools/SearchCompilerQueryWizard.java	(working copy)
@@ -46,7 +46,7 @@
      * @return an Overpass QL query
      * @throws UncheckedParseException when the parsing fails
      */
-    public String constructQuery(final String search) {
+    public static String constructQuery(final String search) {
         try {
             Matcher matcher = Pattern.compile("\\s+GLOBAL\\s*$", Pattern.CASE_INSENSITIVE).matcher(search);
             if (matcher.find()) {
@@ -73,7 +73,7 @@
                     throw new IllegalStateException(mode);
                 }
             }
-            
+
             final Match match = SearchCompiler.compile(search);
             return constructQuery(match, "[bbox:{{bbox}}];", "");
         } catch (SearchParseError | UnsupportedOperationException e) {
@@ -81,7 +81,7 @@
         }
     }
 
-    private String constructQuery(final Match match, final String bounds, final String queryLineSuffix) {
+    private static String constructQuery(final Match match, final String bounds, final String queryLineSuffix) {
         final List<Match> normalized = normalizeToDNF(match);
         final List<String> queryLines = new ArrayList<>();
         queryLines.add("[out:xml][timeout:90]" + bounds);
@@ -135,11 +135,15 @@
                     return "[" + (negated ? "!" : "") + quote(key) + "]";
                 case EXACT:
                     return "[" + quote(key) + (negated ? "!=" : "=") + quote(value) + "]";
+                case ANY_KEY: // *=value
+                    // fall through
                 case EXACT_REGEXP:
                     final Matcher matcher = Pattern.compile("/(?<regex>.*)/(?<flags>i)?").matcher(value);
                     final String valueQuery = matcher.matches()
                             ? quote(matcher.group("regex")) + Optional.ofNullable(matcher.group("flags")).map(f -> "," + f).orElse("")
                             : quote(value);
+                    if (mode == SearchCompiler.ExactKeyValue.Mode.ANY_KEY)
+                        return "[~\"^.*$\"" + (negated ? "!~" : "~") + valueQuery + "]";
                     return "[" + quote(key) + (negated ? "!~" : "~") + valueQuery + "]";
                 case MISSING_KEY:
                     // special case for empty values, see https://github.com/drolbr/Overpass-API/issues/53
