简体   繁体   English

在PowerShell中用双引号拆分字符串

[英]Split string with double quotes in PowerShell

I have a file with similar lines like the following:我有一个类似行的文件,如下所示:

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."

My goal is to split this text in the different attributes:我的目标是将此文本拆分为不同的属性:

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.'

What I am currently using is 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
    }
}

With that code I can extract one attribute at a time.使用该代码,我可以一次提取一个属性。 But it does not work with double quotes:但它不适用于双引号:

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

The result is:结果是:

'Please add a '

and the rest is missing.其余的都不见了。 The expected result should be:预期的结果应该是:

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

Is anyone able to help me?有谁能帮助我吗?

Thanks!谢谢!

Edit: I have created a poor-mans solution by replacing the bad double quotes with something else, then splitting the text and replace again.编辑:我通过用其他东西替换坏的双引号创建了一个穷人的解决方案,然后拆分文本并再次替换。 Not nice, but works:不好,但有效:

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
    }
}

You can do this changes without function:您可以在没有功能的情况下进行此更改:

$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

Additional (if you read your data from file) :附加(如果您从文件中读取数据)

$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}
}
}

Now $customdata is array that have two properties ID and text and you can get data from it by $customdata.ID $customdata.text .If you need write some output you run it in foreach loop and formating your output.现在$customdata是具有两个属性IDtext数组,您可以通过$customdata.ID $customdata.text从中获取数据。如果您需要编写一些输出,您可以在 foreach 循环中运行它并格式化您的输出。

I would consider to use the Import-Csv cmdlet or the onvertFrom-Csv cmdlet for this:我会考虑为此使用Import-Csv cmdlet 或onvertFrom-Csv cmdlet:

To set the property Name and Value based on the included <name>=<value> format:根据包含的<name>=<value>格式设置属性NameValue

# 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

Results:结果:

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.

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM