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».)