regex facultatif correspondance de mot

J’essaie de créer une regex pour extraire des chanteurs, des paroliers. Je me demandais comment rendre la recherche de paroliers facultative.

Exemple de chaîne multiligne:

Fireworks Singer: Katy Perry Vogue Singers: Madonna, Karen Lyricist: Madonna 

Regex: /Singers?:(.\*)\s?Lyricists?:(.\*)/

Cela correspond à la deuxième ligne correctement et extrait les Singers(Madonna, Karen) et les Lyricists(Madonna)

Mais cela ne fonctionne pas avec la première ligne, quand il n’y a pas de paroliers.

Comment puis-je rendre la recherche par Lyricists facultative?

Vous pouvez inclure la partie que vous souhaitez faire correspondre dans un groupe non capturé: (?:) . Ensuite, il peut être traité comme une seule unité dans le regex, et ensuite vous pouvez mettre un ? après cela pour le rendre facultatif. Exemple:

 /Singers?:(.*)\s?(?:Lyricists?:(.*))?/ 

Notez qu’ici le \s? est inutile puisque .* mangera avidement tous les personnages, et aucun retour en arrière ne sera nécessaire. Cela signifie également que la partie (?:Lyricists?:(.*)) Ne correspondra jamais pour la même raison. Vous pouvez utiliser la version non gourmande de .* .*? avec le $ pour résoudre ce problème:

 /Singers?:(.*?)\s*(?:Lyricists?:(.*))?$/ 

Certains espaces blancs finissent par être capturés; ceci peut être enlevé aussi, donnant une expression finale de:

 /Singers?:\s*(.*?)\s*(?:Lyricists?:\s*(.*))?$/ 

Juste pour append à la solution de Cameron. Si la chaîne source contient plusieurs lignes contenant à la fois des chanteurs et des paroliers, vous devrez probablement append le modificateur multiligne ‘m’ pour que “$” corresponde aux extrémités des lignes. (Vous n’avez pas dit quelle langue vous utilisez – vous pouvez également append le modificateur «i».)