web-dev-qa-db-fra.com

Comment puis-je écrire une regex qui correspond à non gourmand?

J'ai besoin d'aide sur la correspondance d'expression régulière avec l'option non gourmande.

Le motif de correspondance est:

<img\s.*>

Le texte à rechercher est:

<html>
<img src="test">
abc
<img
  src="a" src='a' a=b>
</html>

Je teste sur http://regexpal.com

Cette expression correspond à tout le texte du <img au dernier >. J'ai besoin que cela corresponde au premier > rencontré après le <img initial;.

J'ai essayé toutes les combinaisons de non-gourmands ?, sans succès.

254
Pointer Null

Le ? non-gourmand fonctionne parfaitement. C'est juste que vous devez sélectionner l'option dot correspond à toutes les options dans les moteurs de regex (regexpal, le moteur que vous avez utilisé a également cette option) que vous testez. En effet, les moteurs de regex ne correspondent généralement pas aux sauts de ligne lorsque vous utilisez .. Vous devez leur indiquer explicitement que vous souhaitez également faire correspondre les sauts de ligne avec ..

Par exemple,

<img\s.*?>

fonctionne bien!

Vérifiez les résultats ici .

Lisez également à propos de comment dot se comporte dans différents goûts de regex.

368
Pavan Manjunath

L'opérande ? établit une correspondance non gourmande. Par exemple. .* est gourmand alors que .*? ne l’est pas. Vous pouvez donc utiliser quelque chose comme <img.*?> pour faire correspondre la balise entière. Ou <img[^>]*>.

Mais rappelez-vous que l'ensemble du code HTML ne peut pas être analysé avec les expressions régulières.

60
Ilya

Question relative au débordement de pile Que veulent dire paresseux et gourmand dans le contexte des expressions régulières? ainsi que.

Gourmand signifie faire correspondre la plus longue chaîne possible.

Lazy signifie faire correspondre la chaîne la plus courte possible.

Par exemple, le gourmand h + l correspond à «enfer» dans «bonjour», mais le paresseux h + + l correspond à «hel».

1
Rahul

Les autres réponses ici supposent que vous ayez une expression rationnelle qui prenne en charge l’appariement non gourmand, une extension introduite dans Perl 5 et largement copiée dans d’autres langues modernes; mais ce n'est pas du tout omniprésent. De nombreux langages et éditeurs plus anciens ne prennent en charge que les expressions régulières traditionnelles, qui ne disposent d'aucun mécanisme pour contrôler la gourmandise de l'opérateur de répétition * - il correspond toujours à la chaîne la plus longue possible.

L'astuce consiste alors à limiter ce qui est autorisé à correspondre en premier lieu. Au lieu de .*, vous semblez chercher

[^>]*

qui correspond toujours autant que de quelque chose que possible; mais le quelque chose n'est pas simplement . "n'importe quel caractère" mais "tout caractère qui n'est pas >.

En fonction de votre application, vous pouvez ou non activer une option permettant à "n'importe quel caractère" d'inclure des nouvelles lignes.

Même si votre moteur regex prend en charge la correspondance non gourmande, il est préférable de préciser ce que vous voulez réellement dire. Si ceci est ce que vous voulez dire, vous devriez probablement le dire, au lieu de vous fier à une correspondance non gourmande avec (espérons-le, probablement) Faites ce que je veux dire.

Bien sûr, ce n’est toujours pas ce que vous voulez si vous avez besoin de manipuler <img title="quoted string with > in it" src="other attributes"> and perhaps <img title="nested tags"> mais à ce stade, vous devriez enfin renoncer à utiliser regex pour cela, comme nous vous l'avions tous dit au départ.

0
tripleee