PowerShell - заменить несколькими вхождениями рядом друг с другом в строке - PullRequest
3 голосов
/ 14 июля 2020

У меня есть | файл с разделителями, и у меня есть данные, где для нулевых значений есть пробел. Итак, в моем файле данных у меня будет что-то вроде этого:

2080| | | | | | | | | | | | | |2000225

Я пробовал это:

-replace '\| \|', '||'

, но он соответствует парам | и все еще оставляет пространство, когда это делается между |. Я просто не очень хорошо разбираюсь в регулярных выражениях и совершенно новичок в Powershell.

2080|| || || ....|2000225

Я не уверен, что рекурсия решит эту проблему или мне нужно будет написать короткую программу Java сделать это.

Ответы [ 3 ]

4 голосов
/ 14 июля 2020

Вы можете использовать оператор regex на основе -replace следующим образом:

PS> ' |2080| | | | | | | | | | | | | |2000225| ' -replace ' (\||$)', '$1'
|2080||||||||||||||2000225|

Этот предполагает, что нет non- пустые поля имеют завершающие пробелы - если они есть, их (последний) конечный пробел будет удален; чтобы избежать этого, используйте соответствующее решение из полезного ответа Виктора Стрибьева .

Regex (\||$) соответствует одиночному пробелу. за которым следует либо литерал | (экранированный как \|), либо (|) конец строки ($); $1 в строке замены затем заменяет все, что соответствует первой группе захвата ((...)); то есть, если пробел char. за ним следует буквальный |, он фактически заменяется просто |; если за ним следует конец строки , это эффективно удаляется .

A небольшое упрощение заключается в использовании утверждения положительного просмотра ((?=...)), которое также используется в ответе Виктора, который захватывает только символ пробела и, следовательно, допускает пропуск текст подстановки -replace операнд, который по умолчанию имеет значение пустая строка и, следовательно, эффективно удаляет пробелы:

PS> ' |2080| | | | | | | | | | | | | |2000225| ' -replace ' (?=\||$)'
|2080||||||||||||||2000225|
1 голос
/ 15 июля 2020

Для этого вам не нужно запускать рекурсивную функцию. Просто запустите его дважды. Проблема в том, что как только вы сопоставите | |, вы пройдете начало следующего вхождения. В первом проходе вы оставляете все вхождения | | | (поэтому после первого совпадения <| |> | у вас будет | в качестве отправной точки для новых совпадений, что не совпадает) для второго ... или если у вас есть больше, вы остались без сопоставления всех четных вхождений, которые слиплись. Если вы запустите его только второй раз, вы сопоставите и измените все совпадения, которые вы оставили в первый раз. Запустите его второй раз, и вы увидите, что он работает.

Просто сделайте:

PS> ' |2080| | | | | | | | | | | | | |2000225| ' -replace '| |', '||' -replace '| |', '||'
|2080||||||||||||||2000225|

Больше вам не понадобится.

1 голос
/ 14 июля 2020

Используя -replace с поиском на основе регулярных выражений, вы можете ....

Удалить все пробелы между двумя | символами:

$text -replace '(?<=\|)\s+(?=\|)'

Чтобы удалить только пробелы между ними | и начало / конец строки

$text -replace '(?<=\||^)\s+(?=\||$)'
$text -replace '(?<![^|])\s+(?![^|])'

Удалите все пробельные символы, за которыми следует | или конец строки

$text -replace '\s+(?=\||$)'
$text -replace '\s+(?![^|])'

Вывод: 2080||||||||||||||2000225. См. демонстрацию регулярных выражений .

Подробности

  • \s+ - 1 или несколько символов пробела
  • (?=\||$) - положительный просмотр вперед, требующий | char (\|) или (|) конца строки ($) непосредственно справа от текущего местоположения.
  • (?![^|]) - отрицательный просмотр вперед, при котором не удается найти совпадение, если сразу справа от текущего местоположения стоит символ, отличный от |.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...