2
votes

Impossible d'avoir uniquement des chiffres dans la séquence de sous-parties d'URL

Je veux changer l'expression régulière pour qu'elle corresponde si le groupe de classe n'a pas que des chiffres entre deux barres obliques:

$regex = "~^upload/(?<class>[/a-z0-9_\.]+)/(?<id_table>\d+)$~";

preg_match($regex, "upload/.bes/.ur/13"); // returns true
preg_match($regex, "upload/.tables/fewf/.u23ser/15"); // returns true
preg_match($regex, "upload/.t/les2/.uer/11"); // returns true
preg_match($regex, "upload/1.tales/.user2/01"); // returns true

preg_match($regex, "upload/23/21"); // returns false
preg_match($regex, "upload/.tables/00/31"); // returns false
preg_match($regex, "upload/6/.uer/q/51"); // returns false


2 commentaires

Il vous manque les délimiteurs. Cela devrait entraîner des messages d'erreur.


Merci. J'ai oublié de les écrire.


3 Réponses :


0
votes

Peut-être que nous pourrions simplifier cela avec cette expression:

^(upload\/.*?)[0-9]+$

Si le groupe de capture de gauche renvoie TRUE, alors c'est faux, sinon ce serait TRUE.


DEMO

Test

true 
true 
true 
true 
false 
true 
false 
true 
false 
true 

Output

$re = '/(\/[0-9]+\/)|([0-9]+$)/m';
$str = 'upload/.bes/.ur/13
upload/.tables/.u23ser/15
upload/.tles2/.uer/11
upload/1.tales/.user2/01

upload/23/21
upload/.tables/00/31
upload/6/.uer/51';

preg_match_all($re, $str, $matches, PREG_SET_ORDER, 0);

foreach ($matches as $match) {
    if (sizeof($match) == 2) {
        echo "false \n";
    } elseif (sizeof($match) == 3) {
        echo "true \n";
    } else {
        "Something is not right!  \n";
    }
}

Une fois le filtrage des chaînes indésirables terminé, nous pouvons simplement capturer ces classes avec :

(\/[0-9]+\/)|([0-9]+$)

DEMO 2


3 commentaires

Je ne suis pas intéressé par . Seulement à propos de sans savoir combien de barres obliques il a.


J'ai besoin de ce groupe Emma. J'ai besoin de cette .


Merci pour l'aide quand même.



0
votes

Vous pouvez utiliser

$regex = "~^upload/(?<class>(?!\d+/)[a-z0-9_.]+(?:/(?!\d+/)[a-z0-9_.]+)*)/(?<id_table>\d+)$~";

Voir cette démo regex a >.

Le modèle de groupe nommé classe correspond à

  • (?! \ d + /) [a-z0-9 _.] + - une ou plusieurs lettres ASCII minuscules, chiffres, _ ou . , mais pas si tous ces caractères sont des chiffres
  • (?: / (?! \ d + /) [a-z0-9 _.] +) * - zéro ou plusieurs répétitions de
    • / - un / caractère
    • (?! \ d + /) [a-z0-9 _.] + - une ou plusieurs lettres ASCII minuscules, chiffres, _ ou . , mais pas si tous ces caractères sont des chiffres


10 commentaires

[^ /] ne m'aide pas. J'ai besoin dans le groupe uniquement de ces caractères [/ a-z0-9_ \.].


@ Arșavin Ok, voir la modification. Notez que vous n'avez pas besoin d'échapper à un point dans une classe de caractères, il correspond à un point. Ce n'est pas le but, le point est la recherche négative.


@ Arșavin Vous avez égaré le lookahead, voici la démo correcte .


Ouais. Mais ne correspond de toute façon pas. S'il vous plaît, analysez-le.


@ Arșavin Essayez de remplacer votre modèle de classe par (? (?! \ D + /) [a-z0-9 _.] + (?: / (?! \ D + /) [a-z0-9_. ] +) *) . Voir regex101.com/r/czCbn8/3


Réellement. J'ai trouvé la réponse: (? (\ D [a-z0-9 _.] + /) +)


@ Arșavin Mais cela permet des / consécutifs et nécessite au moins 2 caractères dans une sous-partie. C'est une mauvaise idée.


Alors, comment y remédier?


@ Arșavin Voir ma réponse mise à jour. Et le lien ci-dessus vers le modèle global.


Merci pour votre temps.



1
votes

Vous pouvez réécrire votre capture nommée en commençant par la classe de chiffres avec un quantificateur possessif:

(?<class>\d*+[a-z0-9_.]+(?>/\d*+[a-z0-9_.]+)*)

Puisque le quantificateur est possessif, vous êtes sûr que le premier caractère correspondant à [a -z0-9 _.] + n'est pas un chiffre.


3 commentaires

@ Arșavin: ce n'est pas un problème, ça marche aussi. regex101.com/r/uoyXdq/1


En effet. J'ai fait des tests. C'est mieux parce que je ne correspond pas à la dernière barre oblique, dont je n'ai pas besoin. T'es cool.


Mais Wiktor Stribiżew a répondu le premier et j'ai déjà accepté sa réponse.