PHP et expressions régulières: les bases pour les débutants

En prévision du démarrage d'un nouveau fil de discussion sur le cours «Backend-developer in PHP» , ainsi que le cours connexe «Framework Laravel» , nous souhaitons partager l'article préparé par notre auteur indépendant.

Attention! Cet article n'est pas pertinent pour le programme de cours et ne sera utile qu'aux débutants . Pour une connaissance plus approfondie, nous vous invitons à visiter un intensif en ligne gratuit de deux jours sur le thème: "Créer un télégramme-bot pour commander du café dans une institution et payer en ligne . " La deuxième journée d'intense aura lieu ici .




Bonjour à tous! Tous avec la prochaine [20]{2,}0 année. Aujourd'hui, je veux aborder un sujet qui est parfois un sujet de blagues de "Pourquoi avez-vous besoin d'apprendre tout cela si vous avez déjà des solutions toutes faites" à "pouvez-vous également apprendre tout Perl?" Cependant, le temps passe, de nombreux programmeurs commencent à maîtriser les expressions régulières, et sur Habré il n'y a pas un seul article récent ( bien que les expressions régulières n'aient pas trop changé ces derniers temps ) sur ce sujet. Il est temps d'en écrire un autre!


Expressions régulières isolées de leur implémentation spécifique


Les expressions régulières (désignées en anglais par RegEx ou regex ) sont un outil utilisé pour diverses options d'étude et de traitement de texte: recherche, vérification, recherche et remplacement d'un élément composé de lettres ou de chiffres (ou de tout autre caractère dans y compris les caractères spéciaux et les signes de ponctuation). Initialement, des expressions régulières sont venues au monde de la programmation à partir de l'environnement de la recherche scientifique, qui a été réalisée dans les années 50 dans le domaine des mathématiques.

Des décennies plus tard, les principes et les idées ont été transférés dans l'environnement du système d'exploitation UNIX (en particulier, ils ont été inclus dans l'utilitaire grep ) et ont été mis en œuvre dans le langage de programmation Perl, qui à l'aube d'Internet était largement utilisé sur le backend (et est à ce jour utilisé, mais déjà moins) pour une telle tâche comme la validation du formulaire.



S'ils semblent simples, pourquoi sont-ils si effrayants à première vue?

En fait, toute expression peut être «régulière» et peut être utilisée pour vérifier ou rechercher des caractères. Par exemple, les mots Pavel ou example@mail.ru peuvent également être utilisés comme habitués, uniquement, bien sûr, dans une clé assez étroite. Pour tester les performances des expressions régulières dans l'environnement PHP sans démarrer votre serveur ou votre hébergement, vous pouvez utiliser le service en ligne suivant (il ne fonctionnait tout simplement pas avec le traitement des caractères russes). Pour commencer, nous utilisons simplement Pavel comme expression régulière.

Supposons que nous ayons le texte suivant:

Pavel en sait trop. Pavel utilise nginx et il n'est pas un randonneur.

Maintenant, les expressions régulières ont trouvé les deux occurrences du mot Pavel. C'est génial, mais cela ne semble pas très utile (sauf si pour une raison quelconque vous essayez d'analyser quelque chose comme la quantité de mention du mot monsieur dans War and Peace via Vim et Python, mais je n'ai pas de questions pour vous).

Variabilité de l'expression

Si votre expression régulière est variable (par exemple, vous n'en connaissez qu'une partie et devez trouver le nombre d'occurrences d'années, à partir de 2000 et se terminant par 2099), alors nous pouvons utiliser l'expression régulière suivante: 20 ..

Texte: Les jeunes écrivains écrivent beaucoup de choses. Par exemple, un écrivain né en 2002 est très différent de 2008 et 2012.

Ici, à l'aide d'expressions régulières, nous pouvons trouver toutes les années, mais jusqu'à présent, cela n'a aucun sens. Très probablement, nous n'avons pas besoin d'années au-delà de 2012 (bien que les jeunes écrivains de moins de 8 ans puissent être offensés, mais pas à ce sujet maintenant). Cela vaut la peine d'étudier les jeux de caractères, mais plus à ce sujet plus tard, car maintenant nous allons parler d'une autre partie importante des expressions régulières: les métacaractères d'échappement.

Imaginez que nous devons trouver le nombre d'occurrences de fichiers avec l'extension .doc (supposons que nous exportons uniquement certains fichiers téléchargés dans notre base de données). Mais un point signifie-t-il simplement n'importe quel caractère? Alors que faire?
Ici, échapper des métacaractères avec une barre oblique inversée vient à notre aide. Maintenant, l'expression \.doc réussira suffisamment pour rechercher toute mention de texte avec l'extension .doc :

Expression régulière: \.doc

Texte: kursach .doc , nepodozritelneyfail.exe , work .doc , shaprgalka.rtf doc

Comme vous pouvez le voir, nous pouvons trouver avec succès le nombre de fichiers avec l'extension .doc dans la liste. Cependant, nous ne pouvons pas extraire les noms de fichiers complets à l'aide de cette expression régulière, par exemple, dans un tableau. Il est temps de jeter un œil aux jeux de caractères.

Correspond à tout un ensemble de personnages

Dans les expressions régulières, la correspondance avec un ensemble est fournie à l'aide de métacaractères - crochets [ ] . Deux caractères ASII peuvent être spécifiés comme début et fin d'une plage. Pour une implémentation simple, supposons que nous voulons trouver tous les fichiers numérotés de 0 à 9 avec l'extension .jpg .

Expression régulière: [0-9]\.jpg

Texte: 1.jpg , 2.jpg , 3.jpg , photo.jpg, anime.jpg, 8.jpg , jkl.jpg

Il convient de noter que le nom de fichier de plus de 1 chiffre ne sera pas couvert par notre expression régulière. Les choix multiples seront un peu plus bas, mais imaginez pour l'instant que nous devions soudainement obtenir le résultat inverse. Ajoutez le métacaractère ^ (qui, au contraire, a jusqu'à deux fonctions dans les expressions régulières). Pour l'utiliser comme exception, vous devez l'ajouter exactement à notre ensemble:

Expression régulière: [^0-9]\.jpg

Texte: 1.jpg, 2.jpg, 3.jpg, phot o.jpg , anim e.jpg , 8.jpg, jk l.jpg

Mais sans choix multiple, ce sont bien sûr des expressions inférieures.

Tableaux utiles

Voici un tableau de métacaractères:

\échapper au métacaractère en tant que personnage régulier
^rechercher un caractère spécifique au début de la ligne (mais uniquement si vous l'excluez de l'ensemble [])
$fin de ligne
|alternative
()regroupement
\ wtous les caractères alphanumériques (pour une raison quelconque, de nombreux manuels ne sont pas d'accord sur les caractères numériques)
\ Wmême chose, juste le contraire
\ stout espace
\ Saucun espace non


Tableau des métacaractères des espaces blancs
[\ b]retour d'un seul caractère
\ ftraduction de page
\ nsaut de ligne
\ rretour chariot
\ ttabulation
\ vonglet vertical


Choix multiple: simplification de la validation


Armé des connaissances acquises, nous allons essayer de faire une expression régulière qui trouve, par exemple, des mots de moins de 3 lettres (une tâche standard pour l'anti-spam). Si nous essayons d'utiliser l'expression régulière suivante - \w{1,3} (dans laquelle le métacaractère \w indique n'importe quel caractère, et les accolades indiquent le nombre de caractères de combien à combien, alors nous mettrons en surbrillance tous les caractères dans une rangée - vous devez en quelque sorte désigner début et fin des mots dans le texte, pour cela nous avons besoin du métacaractère \b .

Expression régulière: \b\w{1,3}\b:

Texte: bon mot
pas
oeuf

Pas mal! Désormais, les mots de moins de trois lettres ne pourront pas entrer dans notre base de données. Regardons la validation de l'adresse postale:

Expression régulière: \w+@\w+\.\w+

Exigences: dans l'e-mail au début doit être n'importe quel caractère (chiffres ou lettres, car l'e-mail, qui ne se compose que de chiffres au début, est assez courant). Vient ensuite le symbole @ , puis autant de caractères que vous le souhaitez, suivi d'un point échappé (c'est-à-dire juste un point) et d'un domaine de premier niveau.

Envisagez la répétition des caractères

Voyons maintenant de plus près comment répéter les caractères dans les expressions régulières. Par exemple, vous voulez trouver n'importe quelle combinaison de nombres de 2 à 6 dans le texte:

Expression régulière: [2-6]+

Texte: Voici les 89 différents 234 chiffres de 24 .

Permettez-moi de vous donner un tableau de tous les quantificateurs de métacaractères:

*les caractères répètent 0 et à l'infini
+répété de 1 à l'infini
{n}répéter exactement n fois
{n,}de n à l'infini
{n1, n2}de n1 à n2 fois exactement
?0 ou 1 caractère, pas plus


Il n'y a rien de compliqué à appliquer des quantificateurs. Sauf pour une mise en garde: quantificateurs gourmands et paresseux. Voici le tableau:

**?
++?
{n,}{n,}?


Les quantificateurs paresseux diffèrent des gourmands en ce sens qu'ils saisissent le nombre minimum, pas le maximum, de caractères. Imaginez que nous ayons la tâche de trouver toutes les balises de titre h1-h6 et leur contenu, et le reste du texte ne devrait pas être affecté (j'ai délibérément entré la balise h7 inexistante afin de ne pas souffrir de la fuite des balises Habré):

Expression régulière: <h [1-7]>. *? <\ / H [1-7]>

Texte: < h7 > bonjour </ h7 > lorem ipsum avada kedavra < h7 > acheter < /h7 >

Tout a fonctionné avec succès, mais uniquement grâce au quantificateur paresseux. Dans le cas de l'utilisation du quantificateur gourmand, tout le texte entre les balises ressortirait (je pense que cela n'a pas besoin d'une illustration).

Bordures de chaîne de caractères

Les limites des chaînes de caractères que nous avons déjà utilisées ci-dessus. Voici un tableau plus détaillé:

\ blimite de mot
\ Bpas de limite de mot
\ Adébut de ligne
\ Zfin de ligne
\ Gfin de l'action


Travailler avec des sous-expressions

Les sous-expressions dans les expressions régulières sont effectuées à l'aide du métacaractère de groupe () .
Voici un exemple d'une expression régulière qui peut universellement trouver diverses variantes d'adresses IP.

Expression régulière: (((25 [0-5]) | (2 [0-4] \ d) | (1 \ d {2}) | (\ d {1,2})) \.) {3} (((25 [0-5] | (2 [0-4] \ d) | (1 \ d {2}) | (\ d {1,2})))))

Texte: 255.255.255.255 n'est qu'une adresse
191.198.174.192 wikipedia
87.240.190.67 vk
31.13.72.36 facebook

Il utilise l'opérateur logique | (ou) qui nous permet de composer une expression régulière qui correspond à la règle de compilation des adresses IP. L'adresse IP doit contenir de 1 à 3 chiffres, dans lesquels trois nombres peuvent commencer par 1, par 2 (ou alors le deuxième chiffre doit être compris entre 0 et 4), ou commencer par 25, puis 3 chiffres s'avère être compris entre 0 et 5. De plus, il doit y avoir un point entre chaque combinaison de nombres. En utilisant les tableaux ci-dessus, essayez de déchiffrer l'expression régulière en haut. Les expressions régulières au début vous font peur avec leur long, mais long ne signifie pas complexe.

Regardez devant

Pour afficher une expression pour n'importe quelle combinaison de certains caractères, un modèle est indiqué par lequel une correspondance est détectée, mais pas renvoyée. Essentiellement, regarder vers l'avant définit une sous-expression et, par conséquent, elle est formée en conséquence. Le modèle de syntaxe pour regarder vers l'avenir consiste en une sous-expression qui est précédée de? =, Puis le texte à mettre en correspondance est également suivi.

Voici une tâche spécifique: il y a un mot de passe qui doit être composé d'au moins 7 caractères et doit obligatoirement comprendre au moins une lettre majuscule et un chiffre. Ici, tout sera un peu plus compliqué, car l'utilisateur devrait pouvoir mettre la majuscule au début et au milieu de la phrase (et la même chose devrait être répétée avec la lettre).

Par conséquent, nous devons anticiper l'expression. De plus, nous devons diviser les signes en groupes. Et je veux limiter ses tailles de 8 à 22 caractères:

Expression régulière: /^(?=.*[az])(?=.*[AZ])(?=.*\d)[a-zA-Z\d]{8,}$/

Texte: Qwerty123
Im789098
mot de passe faible

Caractéristiques du travail des expressions régulières en PHP


Pour savoir comment les expressions régulières fonctionnent en PHP, consultez les fonctions de la documentation officielle PCRE (Perl Compatible Regular Expressions), qui est disponible sur le site officiel. L'expression doit être entourée de délimiteurs, par exemple, dans des barres obliques.

Les caractères arbitraires peuvent être un délimiteur, sauf alphanumérique, barre oblique inverse "\" et zéro octet. Si le caractère délimiteur apparaît dans le modèle, il doit être échappé \. En tant que séparateurs, les combinaisons proviennent de Perl: (), {}, [].

Quelles fonctions sont utilisées en php? Le package PCRE fournit les fonctionnalités suivantes pour prendre en charge les expressions régulières:

  • preg_grep () - Effectue une recherche et retourne un tableau de correspondances.
  • preg_match () - recherche la première correspondance en utilisant des expressions régulières
  • preg_match_all () - Effectue une recherche globale à l'aide d'expressions régulières
  • preg_quote () - prend un modèle et retourne sa version échappée
  • preg_replace () - effectue une opération de recherche et de remplacement
  • preg_replace_callback () - effectue également une opération de recherche et de remplacement, mais ils utilisent le rappel - une fonction pour tout remplacement spécifique
  • preg_split () - divise une chaîne de caractères en sous-chaînes


Le modificateur i pour organiser les correspondances sans respecter la casse.
Le modificateur m vous permet d'activer le mode de traitement de texte multiligne.

Le remplacement des chaînes peut être calculé en tant que code PHP. Pour activer ce mode, utilisez le modificateur e .

Toutes les fonctions preg_replace() , preg_replace_callback() et preg_split() prennent en charge un argument supplémentaire, qui introduit des restrictions sur le nombre maximal de remplacements ou de partitions.

Les backlinks peuvent être indiqués par le signe $ (par exemple, $ 1), et dans les versions antérieures, les signes \\ sont utilisés à la place du signe $.
Les métacaractères \ E, \ l, \ L, \ u et \ U ne sont pas utilisés (par conséquent, ils n'étaient pas mentionnés dans cet article).

Notre article serait incomplet sans les classes de caractères POSIX, qui fonctionnent également en PHP (et peuvent en général augmenter la lisibilité de vos habitués, mais tous ne sont pas pressés d'apprendre, car ils brisent souvent la logique de l'expression).

[[: alnum:]]N'importe quelle lettre de l'alphabet ou chiffre anglais
[[: alpha:]]N'importe quelle lettre ([a-zA-Z])
[[: vide:]]Espace blanc ou code de caractère 0 et 255
[[: chiffre:]]N'importe quel chiffre ([0-9])
[[: inférieur:]]N'importe quelle lettre minuscule de l'alphabet anglais ([az])
[[: supérieur:]]N'importe quelle lettre majuscule de l'alphabet anglais ([AZ])
[[: punct:]]Tout signe de ponctuation
[[: espace:]]Tout espace
[[: xdigit:]]N'importe quel chiffre hexadécimal ([0-9a-fA-F])


À la fin, je donnerai un exemple d'une implémentation concrète d'expressions régulières en PHP, en utilisant les implémentations mentionnées ci-dessus. J'ai également ajouté la validation du nom d'utilisateur afin qu'il ne puisse pas entrer des combinaisons de lettres trop courtes (enfin, supposons que ce soient des surnoms, pas des noms, les noms sont plus courts que deux lettres):

  $pattern_name = '/\w{3,}/'; $pattern_mail = '/\w+@\w+\.\w+/'; $pattern_password = '/^(?=.*[az])(?=.*[AZ])(?=.*\d)[a-zA-Z\d]{8,}$/'; if (preg_match($pattern_name, $name) && preg_match($pattern_mail, $mail) && preg_match($pattern_password, $_POST['password'])) { #  ,  ,   ,   ,      } 


Merci à tous pour votre attention! Bien sûr, aujourd'hui, nous n'avons abordé qu'une partie des expressions régulières, et quelques autres articles peuvent être écrits à leur sujet. Par exemple, nous n'avons pas parlé de la mise en œuvre de la recherche de répétitions de mots identiques dans le texte. Mais j'espère que les connaissances acquises sont suffisantes pour écrire de manière significative ma première validation de formulaire et ensuite seulement passer à des choses plus furieuses.

Par tradition, quelques liens utiles:

Aide-mémoire du MIT sur les expressions régulières
La partie officielle de la documentation php regex.

C’est tout. Rendez-vous à l' intensif !
La deuxième journée d'intense aura lieu ici

Source: https://habr.com/ru/post/fr484048/


All Articles