OverpassTurbo: Teilstring im Value eines Keys finden

Hallo,

ich möchte einen Teilstring in Werten des Key phone finden:

[out:json][timeout:25];
{{geocodeArea:Germany}}->.searchArea;
// gather results
(
nwr [~".*"~"116117",i](area.searchArea);
);
// print results
out meta;

Die Fehlermeldung:

Ajax-Fehler
Während des Ausführens der Overpass Query ist ein Fehler aufgetreten!
Request rejected. (e.g. server not found, request blocked by browser addon, request redirected, internal server errors, etc.)
Error-Code: error (0)

Systemfehler oder Fehler in meiner Abfrage? Und: Ist die Abfrage überhaupt richhtig, um z.B. die Werte

  • 116117
  • 0116117
  • +49 116117

zu finden?

Warum nicht einfach

[out:json][timeout:25];
// fetch area “Deutschland” to search in
{{geocodeArea:Deutschland}}->.searchArea;
// gather results
nwr["phone"~"116117"](area.searchArea);
// print results
out geom;

Es gäbe da ja noch fax, contact:phone und contact:fax

Sicher gibt es das, aber die Frage im Ausgangspost war:

was bedeutet, dass die Werte in fax, contact:phone, contact:fax, mobile … irrelevant sind.

Edit:
Beim ärztlichen Bereitschaftsdienst wird gerne auch contact:phone verwendet und auch gerne ein Leerzeichen zwischen 116 und 117.

Will man diese ebenfalls finden, so ergänzt man ein [ ]? für das optionale Leerzeichen und die Suche in weiteren Keys durch Verwendung von Klammern:

[out:json][timeout:25];
// fetch area “Deutschland” to search in
{{geocodeArea:Deutschland}}->.searchArea;
// Findet 116117 und 116 117 in den Keys phone und contact:phone
(
  nwr["phone"~"116[ ]?117"](area.searchArea);
  nwr["contact:phone"~"116[ ]?117"](area.searchArea);
);
  // print results
out geom;

Damit durchsuchst Du allle keys in DE nach dem Muster. Wahrscheinlich überlastet das den Server und es kommt zur gezeigten Fehlermeldung.

Ich bin erstaunt, dass diese Syntax überhaupt durchgeht. Aber tatsächlich scheint es erlaubt zu sein, und wenn man das Matching der Keynamen einschränkt, liefert Overpass auch Ergebnisse:

[out:json][timeout:25];
{{geocodeArea:Germany}}->.searchArea;
// gather results
(
nwr [~"^(contact:.*|phone)$"~"116 *117",i](area.searchArea);
);
// print results
out meta;
2 Likes

Danke @eserte, funktioniert! Wenn ich das richtig sehe findet Deine Code

[contact:]phone == *116[ ]117 # Text in [ist fakultativ]
Aber was bedeuten die Zeichen $"~" *; anders gefragt: Eine Erklärung der Sytax / Sonderzeichen wäre fein …

Reguläre Ausdrücke oder englisch regular expressions (kurz regex) beschreiben Muster. Die Bedeutung einiger Zeichen ist dabei praktisch immer gleich, andere funktionieren je nach Auswerte-Programm unterschiedlich.
Im Netz findet man zig Tutorials, z.B. Regex Tutorial - How to write Regular Expressions? - GeeksforGeeks

Das Dollarzeichen gehört hier noch zum regulären Ausdruck. Die einzelnen besonderen Zeichen erklärt:

  • ^: Anfang der Zeichenkette
  • (: Beginn der Gruppe (in diesem Fall mit mehreren Alternativen)
  • .*: 0 oder mehr beliebige Zeichen
  • |: nächste Alternative in der Gruppe folgt
  • ): Ende der Gruppe
  • $: Ende der Zeichenkette

Mit ^ und $ verhindert man hier, dass auch Zeichenketten wie blaphone oder phonebla erkannt werden.

Danke @eserte für die Erläuterungen, trotzdem noch Fragen:
was bedeutet in

  • der Teil Komma i ,i in nwr [~"^(contact:.*|phone)$"~"116 *117",i](area.searchArea)?
  • Wieso wird dieser node gefunden, in dem der Suchtext in contact:website enthalten ist? Wie müsste die Abfrage lauten, um den Suchtext nur in phone oder contact:phone zu finden.?

,i heisst case-insensitive

Durch das “i” wird die Groß- und Kleinschreibung ignoriert.

Der Node wird gefunden, weil der reguläre Ausdruck so aufgebaut ist. Er findet sowohl Keys mit contact: + beliebigem Text danach, sowie phone.

Siehe auch Overpass QL - Key/value matches regular expression (~“key regex”~“value regex”)


Am einfachsten für dich verständlich wäre wohl folgende Abfrage, in der drei einzelne Abfragen vereint werden:

[out:json][timeout:250];
{{geocodeArea:Germany}}->.searchArea;
(
  nwr["phone"~"116 *117"](area.searchArea);
  nwr["contact:phone"~"116 *117"](area.searchArea);
  nwr[~"^phone:.*$"~"116 *117"](area.searchArea);
);
out meta;

Die findet alle phone-Tags, alle contact:phone-Tags, sowie alle phone:*-Tags (z.B. phone:DE, phone:US)


Falls du Sorge hast, dass dir wegen fehlerhafter Groß-/Kleinschreibung ein Objekt durch die Lappen geht, dann müsstest du auch das “i” wieder in die Abfrage mitaufnehmen.

[out:json][timeout:250];
{{geocodeArea:Germany}}->.searchArea;
(
  nwr[~"^phone$"~"116 *117",i](area.searchArea);
  nwr[~"^contact:phone$"~"116 *117",i](area.searchArea);
  nwr[~"^phone:.*$"~"116 *117",i](area.searchArea);
);
out meta;

Hinweis

Natürlich könnte man die drei Abfragezeilen auch wieder in eine gemeinsame Zeile überführen, aber das macht es nur unnötig kompliziert / schwieriger zu verstehen.

1 Like

.

Das Muster für den Key bedeutet:

  1. contact:.* “contact:” gefolgt von irgend etwas (.*)
    oder
  2. phone
  3. mit den Klammern und ^ am Anfang sowie $ am Ende wird erzwungen, dass das Muster den gesamten String abdeckt

Du meinst phonemit optionalem Präfix contact:
Dazu kannst du als Muster ^(contact:)?phone$ wählen. ? ist ähnlich wie *:
Während * beliebig oft bedeutet,
steht ? für ein oder kein mal also genau was du möchtest: optional..

1 Like

Also wenn man Reguläre-Ausdrücke versteht erscheint mir eine einzeilige Version deutlich einfacher zu erkennen. Die Erweiterung der Länderkennungen sähe dann präziser so aus:

 nwr[~"^(contact:)?phone(:[A-Z]{2})?$"~"116 *117",i](area.searchArea);

Das Muster im Key bedeutet dabei:

  1. Der Text phone mit
  2. dem optionalem Präfix contact: und
  3. dem optionalem Suffix bestehend aus einem Doppelpunkt gefolgt von genau zwei Buchstaben,
  4. was wegen ^ und $ den ganzen Key aufüllen muss.
1 Like

Danke, ich lerne …

Warum funktioniert
nwr [~"^(contact:|phone)$"~"^112$",i](area.searchArea);
aber
nwr [~"^(contact:|phone)$"~"^+49 112$",i](area.searchArea);
liefert einen Fehler?

Das liegt an dem Plus-Zeichen +, dieses ist ein Metazeichen, siehe Regular expression - Wikipedia

In Overpass-Turbo das + mit zwei Backslashs escapen:

nwr [~"^(contact:|phone)$"~"^\\+49 112$",i](area.searchArea);

1 Like

… weil + ein Sonderzeichen wie ?und * ist.
+ ist ähnlich wie * in dem es Wiederholungen erlaubt. Der Unterschied besteht darin, das bei + das vorangehende Muster (im Gegensatz zu *) aber mindestens einmal vorkommen muss.
Wenn du das ‘+’ literal als Pluszeichen im Muster verwenden willst, musst du es mit Backslash \ quotieren:
nwr [~"^(contact:)?phone$"~"^\\+49 112$",i](area.searchArea);

Das gilt übrigens auch für . und wird z.B. in Domain Names (von mir auch :wink:) gerne vergessen.
Das Muster wiki.osm.de würde auch Wörter wie ‘wikiposmade’, ‘wikilosmide’ und ‘wikikosmode’ finden, weil im Muster . für ein beliebiges Zeichen steht. Korrekter müsste das Muster daher als wiki\\.osm\\.de geschrieben werden.

Edit: Ups, Vinzenz war nicht nur ein paar Sekunden schneller, sondern hat auch noch die Tatsache berücksichtigt, dass der Backslash im “String” selbst per weiterem Backslash zu quotieren ist.

1 Like