Регулярное выражение regex

Я пытаюсь создать регулярное выражение для извлечения певцов, лириков. Мне было интересно, как сделать поиск лириков необязательным.

Пример многострочной строки:

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

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

Правильно соответствует второй строке и извлекает Singers(Madonna, Karen) и Lyricists(Madonna)

Но это не работает с первой строкой, когда нет лириков.

Как заставить лириков искать необязательно?

Ответ 1

Вы можете заключить ту часть, которую вы хотите сопоставить, в группе, не участвующей в записи: (?:). Затем его можно рассматривать как единое целое в регулярном выражении, а затем вы можете поместить a ? после него, чтобы сделать его необязательным. Пример:

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

Обратите внимание, что здесь \s? бесполезен, так как .* будет жадно употреблять все символы, и никакого возврата не потребуется. Это также означает, что часть (?:Lyricists?:(.*)) никогда не будет сопоставлена ​​по той же причине. Вы можете использовать не жадную версию .*, .*? вместе с $, чтобы исправить это:

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

Некоторые дополнительные пробелы заканчиваются захватом; это также можно удалить, давая окончательное регулярное выражение:

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

Ответ 2

Просто добавьте к решению Cameron. если в исходной строке есть несколько строк, каждая из которых содержит как певцов, так и лириков, вам, вероятно, потребуется добавить модификатор "m" с несколькими строками, чтобы "$" соответствовал концам строк. (Вы не сказали, на каком языке вы используете - вы также можете добавить модификатор "i".)