Проблема, конечно, заключается в том, что иногда &
разграничивает пути, а иногда это часть пути. Простая замена персонажа не сможет определить, какой &
и какой, поэтому нам нужно использовать некоторый контекст, чтобы понять это.
Мы знаем, что когда &
разграничивает два пути, следующий путь начинается с метки вида pathX=
. Мы можем использовать шаблон &(?=(path\d+=))
для сопоставления с такими &
символами. (?=)
является положительным прогнозом нулевой ширины , что означает, что все внутри него должно следовать &
, но фактически не будет сопоставлено (заменено). path\d+=
означает буквенные символы path
, за которыми следуют одна или несколько цифр (\d+
), за которыми следует буквенный символ =
.
PS> $pattern = '&(?=(path\d+=))'
PS> 'path1=/path/me & you/file.json' -replace $pattern, ';'
path1=/path/me & you/file.json
PS> 'path1=/path/me & you/file.json&path2=/path/you & me/file.txt' -replace $pattern, ';'
path1=/path/me & you/file.json;path2=/path/you & me/file.txt
PS> 'path1=/path/me & you/file.json&path2=/path/you & me/file.txt&path3=/folder/R & B/ me & you/file.txt' -replace $pattern, ';'
path1=/path/me & you/file.json;path2=/path/you & me/file.txt;path3=/folder/R & B/ me & you/file.txt
PS> '&path1=/path/me & you/file.json&path2=/path/you & me/file.txt' -replace $pattern, ';'
;path1=/path/me & you/file.json;path2=/path/you & me/file.txt
PS> 'path1=/path/me & you/file.json&path2=/path/you & me/file.txt&' -replace $pattern, ';'
path1=/path/me & you/file.json;path2=/path/you & me/file.txt&
PS> 'path1=/path/me & you/file.json&&path2=/path/you & me/file.txt&&&&&path3=/folder/R & B/ me & you/file.txt' -replace $pattern, ';'
path1=/path/me & you/file.json&;path2=/path/you & me/file.txt&&&&;path3=/folder/R & B/ me & you/file.txt
Обратите внимание, что ведущий &
(четвертый тестовый вход) заменяется, как и ожидалось, поскольку за ним следует обычный path1=
, но трейлинг &
(пятый тестовый вход) и несколько последовательных &
(последний тест вход) нет. Если эти случаи следует рассматривать как пустые пути, а не имена файлов, оканчивающиеся на &
, это можно сделать с помощью шаблона &+(?=(path\d+=)|$)
. &+
теперь будет соответствовать одному или нескольким &
, а добавление |$
будет также совпадать с &
, встречающимся в конце строки .
PS> $pattern = '&+(?=(path\d+=)|$)'
PS> 'path1=/path/me & you/file.json' -replace $pattern, ';'
path1=/path/me & you/file.json
PS> 'path1=/path/me & you/file.json&path2=/path/you & me/file.txt' -replace $pattern, ';'
path1=/path/me & you/file.json;path2=/path/you & me/file.txt
PS> 'path1=/path/me & you/file.json&path2=/path/you & me/file.txt&path3=/folder/R & B/ me & you/file.txt' -replace $pattern, ';'
path1=/path/me & you/file.json;path2=/path/you & me/file.txt;path3=/folder/R & B/ me & you/file.txt
PS> '&path1=/path/me & you/file.json&path2=/path/you & me/file.txt' -replace $pattern, ';'
;path1=/path/me & you/file.json;path2=/path/you & me/file.txt
PS> 'path1=/path/me & you/file.json&path2=/path/you & me/file.txt&' -replace $pattern, ';'
path1=/path/me & you/file.json;path2=/path/you & me/file.txt;
PS> 'path1=/path/me & you/file.json&&path2=/path/you & me/file.txt&&&&&path3=/folder/R & B/ me & you/file.txt' -replace $pattern, ';'
path1=/path/me & you/file.json;path2=/path/you & me/file.txt;path3=/folder/R & B/ me & you/file.txt