Разделить строку с двойными кавычками в PowerShell - PullRequest
0 голосов
/ 12 марта 2020

У меня есть файл с похожими строками, подобными приведенным ниже:

setmessage id=xxx.yyy.1 "text=Your input is not correct."
setmessage id=xxx.yyy.2 "text=Please add a ""Valid from"" date."
setmessage "id=xxx.yyy.3" "text=Another text, but the ID is in quotes too."

Моя цель состоит в том, чтобы разбить этот текст на различные атрибуты:

id   => 'xxx.yyy.1'
text => 'Your input is not correct.'

id   => 'xxx.yyy.2'
text => 'Please add a ""Valid from"" date.'

id   => 'xxx.yyy.3'
text => 'Another text, but the ID is in quotes too.'

В настоящее время я использую this:

function extractAttribute([String] $line, [String] $attribute){
    if ($line -like "*$attribute*"){
        $return = $line -replace ".*(?=`"$attribute=)`"$attribute=([^`"]*).*|.*$attribute=(.*?)([\r\n].*|$)", "`$1`$2"
        if ($return -eq ""){
            $return = $null
        }
        return $return
    } else {
        return $null
    }
}

С этим кодом я могу извлечь один атрибут за раз. Но он не работает с двойными кавычками:

$line = 'setmessage id=xxx.yyy.2 "text=Please add a ""Valid from"" date."'
$attribute = "text"
$result = extractAttribute $line $attribute

Результат:

'Please add a '

, а остальные отсутствуют. Ожидаемый результат должен быть:

'Please add a ""Valid from"" date.'

Кто-нибудь может мне помочь?

Спасибо!

Редактировать: я создал решение для бедняков, заменив плохое двойные кавычки с чем-то еще, затем разделить текст и заменить снова. Не красиво, но работает:

function extractAttribute([String] $line, [String] $attribute){
    if ($line -like "*$attribute*"){
        $line = $line -replace '""', '~~'

        $return = $line -replace ".*(?=`"$attribute=)`"$attribute=([^`"]*).*|.*$attribute=(.*?)([\r\n ].*|$)", "`$1`$2"

        $return = $return -replace '~~', '""'
        if ($return -eq ""){
            return $null
        } else {
            return $return
        }
    } else {
        return $null
    }
}

Ответы [ 2 ]

0 голосов
/ 12 марта 2020

Я хотел бы использовать для этого командлет Import-Csv или onvertFrom-Csv:

Чтобы задать свойство Name и Value на основе включенного <name>=<value> формата:

# Import-Csv .\Input.txt -Header (0..3) -Delimiter ' ' | ForEach-Object ...
$Content | ConvertFrom-Csv -Header (0..3) -Delimiter ' ' | ForEach-Object {
    $Properties = @{}
    ForEach ($Item in ($_.PSObject.Properties.Value).Where{$_}) {
        $Name, $Value = $Item.Split('=',2)
        $Properties[$Name.Trim()] = "$Value".Trim()
    }
    [pscustomobject]$Properties
} | Select-Object Id, Text

Результаты:

id        text
--        ----
xxx.yyy.1 Your input is not correct.
xxx.yyy.2 Please add a "Valid from" date.
xxx.yyy.3 Another text, but the ID is in quotes too.
0 голосов
/ 12 марта 2020

Вы можете сделать это без функции:

$line = 'setmessage id=xxx.yyy.2 "text=Please add a ""Valid from"" date."'
$attribute = "text="
$result=$line -replace ".*(?<=$attribute)" #select all to and of your attribute and replace it  to nothing

Дополнительно (если вы читаете данные из файла) :

$pattern1="(?<=id=).*?((?=\s)|(?=`"))"
$pattern2="(?<=text=).*(?=`")"
$customdata=@()
$z=Get-Content D:\testdir\sample.txt |ForEach-Object{
$customdata+=[PSCustomObject]@{
ID=$_ |Select-String $pattern1|foreach{$_.Matches.value}
text=$_ |Select-String $pattern2|foreach{$_.Matches.value}
}
}

Сейчас $customdata массив, который имеет два свойства ID и text, и вы можете получить из него данные с помощью $customdata.ID $customdata.text. Если вам нужно записать какой-либо вывод, вы запускаете его в foreach l oop и форматируете свой вывод.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...