Я просто долго пытался придумать работающую маленькую однострочную строчку на Perl, подобную этой:
perl -pe 'if (/^(".*",").*, /) { $a = $1; s/, /"\n$a/g}'
Мои входные данные выглядят примерно так:
"foo","bar a"
"baz","bar a, bar b, bar c"
И я преобразовываю это в это:
"foo","bar a"
"baz","bar a"
"baz","bar b"
"baz","bar c"
По сути, я хотел сопоставить только определенные строки (if (/, /)...
) и в этих строках заменить все экземпляры этого совпадения частью исходной строки. s///g
с группой соответствия не будет работать, потому что она не будет рекурсивно правильно, строка замены должна быть вычислена до того, как замены начнут происходить.
if (/^(".*",").*, /) { s/, /"\n$1/g}
Но это не так. Переменная $1
всегда была пустой. Учитывая то, что написано в документах о сохраняемости, я сюрприз для меня:
Эти переменные соответствия обычно остаются до следующего успешного сопоставления с образцом.
Только когда я начал хранить результат в собственной переменной, я смог получить доступ к результату из выражения подстановки:
if (/^(".*",").*, /) { $a = $1; s/, /"\n$a/g}
Почему $1
очищался, когда не было не только успешного совпадения, но и вообще не было запроса на совпадение в моем поиске и замене? И был ли лучший способ подойти к этой проблеме?