6
votes

Regex \ r ne fonctionne pas à l'intérieur de la classe de caractères

en PHP, le caractère d'échappement \ r code> qui doit correspondre à une séquence de nouvelle ligne ne fonctionne pas dans une classe de caractères.

J'ai récemment appris sur ce caractère spécial sur une autre réponse sur Stackoverflow et Pour être honnête, je n'ai pas été en mesure de trouver beaucoup en ligne pour documenter son existence - nulle part sur php.net n'est-il mentionné, sauf dans un commentaire d'utilisateur. P>

Question (s): P>

  • Pourquoi \ r code> fonctionne à l'intérieur d'une classe de caractères? LI>
  • Où est-il documenté? LI> ul>

    Exemple 1: strong> ( https://regex101.com / r / va8xv3 / 3 ) p> xxx pré>

    retourne (trouve la correspondance, remplacez-la par un seul espace): P>

    line1
    line2
    


9 commentaires

Êtes-vous sûr que c'est valable? Un seul commentaire mentionne que comme travaillant. Vous penseriez que le manuel mentionnerait s'il était en réalité soutenu.


Avec quelle fonction essayez-vous de l'utiliser? PHP prend en charge quelques formats de REGEXP différents - au moins PCRE et POSIX . Pouvez-vous fournir un exemple / un extrait?


Oui c'est valide. Cela fonctionne bien lorsqu'il n'est pas en classe de caractères. Voir ici: Regex101.com/r/va8xv3/1


@Billynoah Pourquoi ne pas utiliser \ n à la place?


@LiMsorsby - Ce n'est pas une question sur la manière de faire correspondre les nouvelles lignes. La question est une question sur l'utilisation et l'explication appropriées ou \ r


@Billynoah Oui, je voulais juste éditer le commentaire pour dire que je sais que cela ne répond pas pourquoi cela ne fonctionne pas mais juste un suget.


Merci, mais je ne cherche pas de suggestions sur la manière de faire correspondre les nouvelles lignes. Veuillez garder les commentaires pertinents pour la question.


"\ B, \ r et \ x ne sont pas spéciaux à l'intérieur d'une classe de caractères. Comme d'autres séquences d'échappement non reconnues, elles sont traitées comme les caractères littéraux" B "," R "et" X "par défaut" - PCRE DOCS - pcre.org/pcre.txt


+1 Sur la question, alors que je doute que de nombreuses personnes connaissent ce scénario, y compris de moi avant de chasser la section pertinente des documents PCRE.


4 Réponses :


3
votes

Ceci est un comportement correct. \ R ne fonctionne que extérieure classe de caractères. (Au moins cela est vrai à Grep et de nombreux autres)

pour Grep:

https: //stat.éthz. CH / R-Manuel / R-Devel / Bibliothèque / Base / HTML / REGEX.HTML

php utilise des expressions de type Perl, alors voir PearDoc:

http://perldoc.perl.org/perlrebackslash.html#misc < / p>

car \ r peut correspondre à une séquence de plusieurs caractères, il ne peut pas être mettre à l'intérieur d'une classe de caractères entre crochets; / [\ R] / est une erreur; Utilisez \ v au lieu


2 commentaires

Je ne vois pas comment cela obtient un uppote. Ma question pose explicitement "pourquoi ne pas travailler dans une classe de personnages?" et vous répondez "\ r ne fonctionne que de classe de caractères en dehors de la classe de caractères". C'est absurde.


Merci d'avoir mis à jour votre réponse avec quelque chose qui contribue à la question. Je n'ai jamais su \ v mais cela m'a fait rire que Regex101.com décrit [\ v] (dans une classe de caractères) car "\ V correspond au caractère v littéralement ( sensible à la casse) ".. qui est faux. Mais ensuite pour faire correspondre réellement à l'espace verticale contraire à sa propre déclaration: Regex101.com/r/wl4ht4/ 1



0
votes

pense que je comprends votre question, Essentiellement une classe de caractères correspond à ce qui entre le [] explicitement, donc dans votre cas [\ r] correspondra à un \ et a R . Par exemple dans la chaîne balhblahrajndsf \ Vous aurez correspondre au \ and r . Cela a-t-il de sens?

http://www.zytrax.com/tech/web/regex.htm < / a>

voir les crochets, les gammes et la négation dans la liaison ci-dessus


5 commentaires

Une barre oblique intégrée à l'intérieur d'une classe de caractères est un caractère spécial et vous devez vous associer que vous auriez besoin d'écrire [\\] , donc non, non, non, vous n'êtes pas correct.


Ici [\ r] correspondre à un littéral r


Si vous essayez de faire correspondre une pause à la ligne, ce n'est pas une minuscule \ r? Voir ce lien régulier-expressions.info/charclass.html


minuscule \ r correspond à la déclaration de chariot. majuscule \ r correspond à la fois \ r et \ n


@Billynoah Keep Calm, je voudrais simplement signaler l'erreur comme vous l'avez fait, en donnant simplement le résultat réel pour laisser l'auteur corriger sa réponse ou la supprimer.



6
votes

du manuel PCRE :

Séquences d'échappement dans les classes de caractères

Toutes les séquences qui définissent une seule valeur de caractère peuvent être utilisées. les classes de caractères à l'intérieur et à l'extérieur. De plus, à l'intérieur d'un Caracticclass, \ b est interprété comme le caractère arrière (HEX 08).

\ n n'est pas autorisé dans une classe de caractères. \ b , \ r et \ x ne sont pas spécial dans une classe de caractères. Comme une autre évasion non reconnue séquences, ils sont traités comme les personnages littéraux "B", "R", et "x" par défaut , mais provoquer une erreur si l'option pcre_extra est définie. Classe Acharacter extérieure, ces séquences ont des significations différentes.

(accent sur le bit pertinent ajouté par moi)


5 commentaires

Merci de googler que pour moi :-) était incapable de trouver cette documentation. Bien que cela n'explique pas pourquoi ni la logique derrière cela, elle définit définitivement le comportement en question.


@billynoah I suspect it's because of the underlying implementation needed to test unicode characters (Exemple ici pour PHP. Cela transformerait une grande surcharge si dans une classe de caractères avec beaucoup d'autres lors du test de toutes les combinaisons. (Encore une fois, je soupçonne que les auteurs de la référence ne pouvaient répondre)


Logique. Fait intéressant, lorsque Dariusz Cichowski indique ci-dessous, \ v est correct de la classe de caractères avec des matchs apparemment identiques. Je pense que le monde a besoin de la police de regex ... ou à tout le moins une nouvelle commande mondiale de regex.


La cause / motif sous-jacente semble être de savoir si une prise de décision est requise pour le métacaracter ...


... \ v et \ r peut avoir des résultats similaires, mais \ v supprime tout espace vertical (nouvelles lignes, onglets verticaux, formes formes) tandis que \ B supprime différentes variétés de nouvelles lignes, spécifiques au verbe de contrôle défini pour l'expression. Donc, \ v a un ensemble statique prédéfini, tandis que \ b utilise un ensemble dynamique basé sur le paramètre BSR. On dirait que \ v est généralement plus rapide et équivalent à \ b , mais pas pour les lignes neuves Unicode, il est donc préférable de ne pas compter complètement sur \ v Pour les scripts nécessitant une assistance Unicode (e-mail analyse l'exemple le plus réel du monde des applications ne s'attendant pas aux utilisateurs entrant des caractères CJK)



1
votes

comme pour la raison pour laquelle \ r n'est pas autorisé dans la classe de caractères, tandis que \ d , \ s , \ w , ... sont autorisés à l'intérieur de la classe de caractères, c'est parce que \ r peut correspondre à la séquence cr lf ( \ r \ n ), qui consiste en 2 points de code. C'est pour la même raison que \ x est interdit de la classe de caractères intérieure, car il correspond à un graphème, qui peut contenir plusieurs points de code.

Une classe de caractères est censé correspondre à une seule unité de point / code de code, ce qui en fait une construction déterministe, en ce sens qu'elle ne nécessite pas de recul. Autoriser une séquence d'unité de point / de code de code à correspondre par une classe de caractères entraîne la longueur de la classe de caractères, complique l'analyse de longueur minimale / de longueur maximale, utilisée dans plusieurs optimisation. Cela nécessite également une modification de la sémantique correspondante. Par exemple, donné [\ r \ n \ r] , doit-il correspondre \ r \ n dans la chaîne "\ r \ n" , ou devrait-il suivre l'ordre déclaré et correspond à seulement \ r ? En cas d'échec, devrions-nous le permettre de reculer?

Je ne suis pas sûr de la mise en œuvre de PCRE. Cependant, en Java, l'analyse de la longueur est utilisée pour optimiser la construction de répétitions (par exemple, avec la répétition de la construction de longueur fixe, vous n'avez pas à stocker la quantité de caractères correspondant à chaque répétition pour la mise en contact), optimisez le cas où la chaîne d'entrée ne fait pas répondre aux exigences minimales de la longueur et déterminez si l'expression dans l'apparence est autorisée ou non.


1 commentaires

Merci pour votre aperçu du raisonnement derrière cela. C'est exactement le genre d'explication que je cherchais. J'aimerais pouvoir accepter deux réponses ici, mais un maigre upvote devra faire. Acclamations