2 votes

Comment faire correspondre une chaîne entre deux limites lorsque seule une ou aucune peut être présente en utilisant une regex

Je veux correspondre à n'importe quelle chaîne de caractères entre deux mots ("Hello" et "Goodbye" dans les exemples suivants) en utilisant une regex.

Les zones en gras dans la liste suivante devraient correspondre:

  • Hello, je t'aime. Goodbye.
  • Hello là, aimes-tu le golf?
  • Je t'aime. Goodbye. À plus tard.

Des exemples de chaînes qui ne devraient pas correspondre du tout incluent (en gros, je veux traiter les mots "Hello" et "Goodbye" comme une sorte de barrière):

  • HelloGoodbye
  • Goodbye, comment vas-tu?
  • Comment vas-tu? Hello

J'ai essayé d'utiliser (?<=Hello).*(?=Goodbye), ce qui fonctionne dans certains cas (voir ici). Le problème avec cette regex est que si par exemple "Goodbye" n'est pas présent, aucun texte après "Hello" ne correspond (et vice versa).

Je ne suis pas sûr que la regex que j'ai essayée soit une bonne solution. Peut-être que je dois simplement correspondre à n'importe quelle partie de la chaîne qui suit "Hello" et/ou précède "Goodbye" (mais aucun des deux n'a besoin d'être présent pour correspondre).

Je pense que j'ai besoin d'avoir une sorte de condition, et je suppose que correspondre aux deux premiers est facile mais je ne trouve pas de moyen de le faire.

Toute aide serait appréciée car je suis encore novice dans l'utilisation des expressions régulières.

2voto

Ryszard Czech Points 10589

Utiliser

(?<=Hello|^)(?:(?!Hello|Goodbye).)+(?=Goodbye|$)

Voir preuve

EXPLICATION

                         EXPLICATION
--------------------------------------------------------------------------------
  (?<=                     regarder derrière pour voir s'il y a :
--------------------------------------------------------------------------------
    Hello                    'Hello'
--------------------------------------------------------------------------------
   |                        OU
--------------------------------------------------------------------------------
    ^                        le début de la chaîne
--------------------------------------------------------------------------------
  )                        fin du regard derrière
--------------------------------------------------------------------------------
  (?:                      groupe, mais ne pas capturer (1 ou plusieurs fois
                           (en faisant correspondre le plus possible)) :
--------------------------------------------------------------------------------
    (?!                      regarder juste après pour voir s'il n'y a pas :
--------------------------------------------------------------------------------
      Hello                    'Hello'
--------------------------------------------------------------------------------
     |                        OU
--------------------------------------------------------------------------------
      Goodbye                  'Goodbye'
--------------------------------------------------------------------------------
    )                        fin de la recherche avant
--------------------------------------------------------------------------------
    .                        n'importe quel caractère sauf \n
--------------------------------------------------------------------------------
  )+                       fin du regroupement
--------------------------------------------------------------------------------
  (?=                      regarder juste après pour voir s'il y a :
--------------------------------------------------------------------------------
    Goodbye                  'Goodbye'
--------------------------------------------------------------------------------
   |                        OU
--------------------------------------------------------------------------------
    $                        avant un \n facultatif, et la fin de la chaîne
--------------------------------------------------------------------------------
  )                        fin de la recherche après

1voto

kriegaex Points 6365

En tant qu'alternative, pas tout à fait aussi sophistiqué que la réponse acceptée et correspondant différemment en cas de mots limites répétés "Hello" et "Goodbye", mais peut-être un peu plus facile à comprendre car il utilise simplement un quantificateur paresseux/réticent *? pour la correspondance et ne recourt pas à un look-behind ou look-ahead:

^(?:.*Hello)?(.*?)(?:Goodbye.*)?$

Les groupes non capturants commençant par (?: assurent que le groupe 1 correspond à ce dont vous avez besoin. Si vous ne vous souciez pas d'utiliser le groupe 2, vous n'avez pas besoin d'utiliser de groupes non capturants du tout. Gardez-le simple! Ensuite, l'expression régulière se lirait ainsi:

^(.*Hello)?(.*?)(Goodbye.*)?$

Vous pouvez tester la première expression régulière ici.

Voir aussi cette feuille de triche des quantificateurs de regex ici.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X