#18301 closed defect (invalid)
Regex in regexp_match are not handled like regex in MapCSS rules
| Reported by: | pyrog | Owned by: | team |
|---|---|---|---|
| Priority: | normal | Milestone: | |
| Component: | Core | Version: | |
| Keywords: | template_report | Cc: |
Description (last modified by )
What steps will reproduce the problem?
See https://josm.openstreetmap.de/wiki/Rules/Pictures
MapCSS rule select all objects with value containing pKey=xxxxx
*[mapillary][mapillary!~/^[a-zA-Z0-9_-]{22}$/][mapillary=~/pKey=[a-zA-Z0-9_-]{22}/] {
Same regex don't match
regexp_match("pKey=([a-zA-Z0-9_-]{22})", tag("mapillary"))
But this one, yes
regexp_match(".*pKey=([a-zA-Z0-9_-]{22}).*", tag("mapillary"))
This like if regexp_match don't have the Perl regex flag g.
(But the doc say that this "flag" is implicit)
Perl uses the g flag to request a match that resumes where the last match left off. This functionality is provided implicitly by the Matcher class: Repeated invocations of the find method will resume where the last match left off, unless the matcher is reset.
Please provide any additional information below. Attach a screenshot if possible.
URL:https://josm.openstreetmap.de/svn/trunk
Repository:UUID: 0c6e7542-c601-0410-84e7-c038aed88b3b
Last:Changed Date: 2019-11-06 00:36:45 +0100 (Wed, 06 Nov 2019)
Build-Date:2019-11-06 02:30:56
Revision:15519
Relative:URL: ^/trunk
Identification: JOSM/1.5 (15519 fr) Mac OS X 10.14.6
OS Build number: Mac OS X 10.14.6 (18G95)
Memory Usage: 1428 MB / 1820 MB (309 MB allocated, but free)
Java version: 1.8.0_221-b11, Oracle Corporation, Java HotSpot(TM) 64-Bit Server VM
Screen: Display 69732928 1280x800
Maximum Screen Size: 1280x800
VM arguments: [-Djava.security.policy=file:<java.home>/lib/security/javaws.policy, -DtrustProxy=true, -Djnlpx.home=<java.home>/bin, -Djava.security.manager, -Djnlpx.origFilenameArg=${HOME}/Library/Application Support/Oracle/Java/Deployment/cache/6.0/31/583aa85f-4a297e61, -Djnlpx.remove=false, -Dsun.awt.warmup=true, -Djava.util.Arrays.useLegacyMergeSort=true, -Djnlpx.heapsize=NULL,2048m, -Dmacosx.jnlpx.dock.name=JOSM (development version), -Dmacosx.jnlpx.dock.icon=${HOME}/Library/Application Support/Oracle/Java/Deployment/cache/6.0/25/4c122699-72a21903.icns, -Djnlp.application.href=https://josm.openstreetmap.de/download/josm-latest.jnlp , -Djnlpx.jvm="<java.home>/bin/java"]
Dataset consistency test: No problems found
Plugins:
+ CADTools (1008)
+ PicLayer (35104)
+ SeaMapEditor (34908)
+ apache-commons (35092)
+ apache-http (34908)
+ cadastre-fr (35194)
+ ejml (35122)
+ geotools (35169)
+ jaxb (35014)
+ jna (34908)
+ jts (35122)
+ opendata (35179)
+ reverter (35084)
+ tag2link (35149)
+ utilsplugin2 (35177)
Tagging presets:
+ https://josm.openstreetmap.de/josmfile?page=Presets/Towers&zip=1
+ https://raw.githubusercontent.com/OpenNauticalChart/josm/master/INT-1-preset.xml
+ https://josm.openstreetmap.de/josmfile?page=Presets/Telecom&zip=1
Validator rules:
+ https://github.com/Jungle-Bus/transport_mapcss/raw/gh-pages/transport.validator.zip
+ ${HOME}/Downloads/Rules_Pictures.validator.mapcss
Last errors/warnings:
- W: No configuration settings found. Using hardcoded default values for all pools.
- W: Region [TMS_BLOCK_v2] Resetting cache
- E: Error header: Version mismatch: Provided 5, server had: 6 of Node 4596808640
- E: Conflits détectés - <html>L’envoi<strong>a échoué</strong> car le serveur possède une version plus récente<br>d’un nœud, chemin ou relation.<br>Le conflit a pour origine le <strong>nœud</strong> avec l’identifiant <strong>4 596 808 640</strong>,<br>le serveur possède la version 6, votre version est 5.<br><br>Cliquez sur <strong>Synchroniser le nœud 4 596 808 640</strong> pour synchroniser uniquement l’objet en conflit.<br>Cliquez sur <strong>Synchroniser tout le jeu de données</strong> pour synchroniser tout le jeu de données.<br>Cliquez sur <strong>Annuler</strong> pour annuler et continuer.<br></html>
- W: Conflits détectés - <html>2 conflits ont été détectés.</html>
- W: Aucunes coordonnées valides n’ont été trouvées
Attachments (0)
Change History (7)
comment:1 by , 6 years ago
| Description: | modified (diff) |
|---|
comment:2 by , 6 years ago
| Description: | modified (diff) |
|---|
comment:3 by , 6 years ago
More details about the context of this issue, in French (as asked by Vincent on Twitter).
À la base, on essaye de mettre en place une règle MapCSS pour faire du nettoyage au niveau de la clé mapillary=*. Mon objectif était de détecter les tags dont les valeurs sont les URLs complètes vers l'image mapillary, au lieu de l'unique identifiant. Et avec une expression régulière, faire une correction automatique.
Donc je commence à écrire cette règle :
*[mapillary][mapillary!~/^[a-zA-Z0-9_-]{22}$/][mapillary=~/pKey=[a-zA-Z0-9_-]{22}/] { throwError: tr("mapillary tag should only contain image ID instead of full URL"); fixAdd: concat("mapillary=", get(regexp_match("pKey=([a-zA-Z0-9_-]{22})", tag("mapillary")),1)); }
Manque de bol, ça ne fonctionne pas. Je cherche pendant une heure la cause du problème, en vain. Yves (qui a ouvert le ticket) cherche également, et finit par trouver la cause du problème : la fonction regexp_match met en correspondance l'expression régulière uniquement si le motif couvre le tag en entier ! Donc adapter en faisant ce code à la place permet d'avoir le résultat attendu :
*[mapillary][mapillary!~/^[a-zA-Z0-9_-]{22}$/][mapillary=~/pKey=[a-zA-Z0-9_-]{22}/] { throwError: tr("mapillary tag should only contain image ID instead of full URL"); fixAdd: concat("mapillary=", get(regexp_match(".*pKey=([a-zA-Z0-9_-]{22}).*", tag("mapillary")),1)); }
Alors qu'intuitivement, on s'attendrait à ce type de comportement uniquement avec une regex de type
^blabla$
(en forçant la recherche jusqu'au début et la fin). Le ticket vise donc à harmoniser la logique des expressions régulières entre le sélecteur MapCSS et cette fonction regexp_match.
(en aparté, j'ai également des soucis avec l'échappement des caractères comme le "/" dans cette même fonction regexp_match, mais je peux créer un ticket distinct pour ça).
comment:4 by , 6 years ago
| Resolution: | → invalid |
|---|---|
| Status: | new → closed |
Mmmokay j'ai compris mais je suis pas chaud du tout pour modifier un comportement qui est là depuis 7 ans (r5699), surtout si vous avez fini par trouver un moyen d'avoir l'expression que vous souhaitiez. Le ticket m'a vraiment embrouillé avec cette histoire de flag g qui serait implicite dans notre doc alors qu'on ne parle pas du tout de ça: la javadoc précise bien qu'on utilise Matcher.matches() et pas Matcher.find(). Je comprends que ça puisse perturber pour les gens habitués à Perl, mais c'est plus ou moins le mode par défaut des regex en Java.
comment:5 by , 6 years ago
Mmmokay j'ai compris mais je suis pas chaud du tout pour modifier un comportement qui est là depuis 7 ans
Tu es bien sûr qu'il ne s'agit pas d'une régression ????!!!
surtout si vous avez fini par trouver un moyen d'avoir l'expression que vous souhaitiez.
C'est un contournement TEMPORAIRE, surtout pour montrer le bug ;)
Pourquoi est-ce un bug ?
Car la même expression dans la ligne MapCSS n'a pas le même comportement que la même expression dans la ligne fixAdd.
Javadoc et le flag g est la seule explication plausible que j'ai trouvé… Je ne suis pas un spécialiste de Java, et encore moins du code de JOSM.
Il y a probablement une autre explication...
En tout cas, en cherchant dans les autres règles comment est utilisé regexp_match j'ai constaté que les expressions étaient de la forme ^expression$.
Donc ce bug - si il existait déjà - n'était pas perceptible.
Merci Vincent de réouvrir ce ticket :)
comment:6 by , 6 years ago
Je comprends la volonté de ne pas casser un comportement présent depuis 7 ans, on peut imaginer peut-être clarifier la documentation (sur le wiki) sur cet aspect pour éviter à d'autres habitués aux regex Perl de ne pas tomber dans le piège ? :-)
comment:7 by , 6 years ago
Euréka : En lisant une doc d'OpenRefine qui est écrit en Java, j'ai fini par comprendre !
En java, il y a plusieurs fonctions pour tester une chaine avec des expression régulières :
- match() qui cherche le motif sur la chaine entière.
- lookingAt() qui cherche depuis le début de la chaine
- find() qui cherche n'importe où dans la chaine.
Source : https://docs.oracle.com/javase/7/docs/api/java/util/regex/Matcher.html
La fonction utilisée dans les expressions du validateur est regexp_match() qui fonctionne comme match().
find() fonctionne comme une expression PCRE avec l'option g
match() fonctionne comme une expression PCRE .*expression.*$
Donc il n'y a pas de bug en soit, plutôt un problème de documentation et/ou avec les exemples utilisés.
Le truc déstabilisant c'est que la regex de la condition mapCSS fonctionne comme find() et que l'expression en dessous utilise match().
Est-ce que find() ou regex_find() est disponible dans les expressions ?
Si oui, ça règle le problème.
Et on pourra mettre à jour la doc…
et vérifier que les validations existantes utilisent bien la même regex dans la ligne MapCSS que dans la ligne "java"
(pour que ça soit plus simple à comprendre, surtout pour les addictes au PCRE :D )
—
Yves



Remove bold