String 将电子邮件字符串转换为.csv列
我有一个巨大的.txt文件,里面充满了这种格式的电子邮件: 多伊,约翰,男;史密斯,简,男 我想知道是否有办法将这个.txt文件转换成一个.csv文件,该文件有两列:一列用于名称,一列用于电子邮件: 第1栏: 多伊,约翰,男 史密斯,简,我是女性 第2栏: JohnD@email.com JaneS@email.comString 将电子邮件字符串转换为.csv列,string,powershell,csv,type-conversion,String,Powershell,Csv,Type Conversion,我有一个巨大的.txt文件,里面充满了这种格式的电子邮件: 多伊,约翰,男;史密斯,简,男 我想知道是否有办法将这个.txt文件转换成一个.csv文件,该文件有两列:一列用于名称,一列用于电子邮件: 第1栏: 多伊,约翰,男 史密斯,简,我是女性 第2栏: JohnD@email.com JaneS@email.com 我有点不知所措如何开始这个,我知道名称中的逗号使这有点复杂。感谢您的任何帮助电子邮件中没有空格,所以类似这样的内容 $content = "Doe, John L (M
我有点不知所措如何开始这个,我知道名称中的逗号使这有点复杂。感谢您的任何帮助电子邮件中没有空格,所以类似这样的内容
$content = "Doe, John L (Male) <JohnD@email.com>; Smith, Jane M (Female) <JaneS@email.com>;"
$content.Split(";") | % { $_.Trim() } | ? { $_ } | % {
$iSpace = $_.LastIndexOf(" "); [PSCustomObject]@{ Name = $_.Substring(0, $iSpace) ; Email = $_.Substring($iSpace+2).TrimEnd(">")
} } | ConvertTo-Csv
在这里,正则表达式可能是最简单的方法。问题是格式可能会有很大差异
$EmailAddresses = 'Doe, John L (Male) <JohnD@email.com>; Smith, Jane M (Female) <JaneS@email.com>;'
$EmailAddresses -split ';' |
Where-Object { -not [string]::IsNullOrWhiteSpace($_) } |
ForEach-Object {
if ($_ -match '\s*(?<Name>.*?)\s*<(?<Email>.*)>\s*') {
[PSCustomObject]@{Name = $Matches['Name']; Email = $Matches['Email'] }
}
else {
Write-Warning "Unrecognized name and email in '$_'"
}
} |
Export-Csv $ExportFile -NoTypeInformation
这将解析您的内容并创建一个包含两列的CSV文件。它将对任何它不理解的条目发出警告,尽管它将忽略任何仅为空白的条目
下面是对正则表达式的解释:
'\s*(?<Name>.*?)\s*<(?<Email>.*)>\s*'
\s*:零个或多个空白字符
?.*:已命名的捕获组“Name”,其中包含一定数量的任意字符
\s*:零个或多个空白字符
\s*:零个或多个空白字符
另一个选项是拆分字符串并将每个字符串转换为System.Net.Mail.MailAddress,该系统具有Address和DisplayName属性。那可能效果最好,但上次我试的时候遇到了麻烦。不幸的是,我不记得是什么问题。我认为显示名称中的逗号有点不合适。下面是一个用正则表达式将文件解析为psobject,然后像往常一样导出为CSV的示例
$In = 'Doe, John L (Male) <JohnD@email.com>; Smith, Jane M (Female) <JaneS@email.com>;' #use get-content here
$SplitInput = $In -split ';' | Where-Object {$_ -ne ''} #filter in case of extra ; at start or end as in example
$Users = $SplitInput | ForEach-Object {
$_ -match '^\s*(?<Name>.*) <(?<Email>.*)>$' | Out-Null
New-Object PSCustomObject @{
Name = $Matches.Name
Email = $Matches.Email
}
}
所用正则表达式的详细信息-您可以执行以下操作:
# Get file contents as string
$fileContents = Get-Content -Path .\sample.txt -Raw
# Split on ; to get each user
# Remove empty entries and trim also
$users = $fileContents.Split(';', [System.StringSplitOptions]::RemoveEmptyEntries).Trim()
# Export each user to CSV file inside this scriptblock
& {
foreach ($user in $users) {
# Get index of last space
$splitIndex = $user.LastIndexOf(' ')
# Create PSCustomObject with Name and Email
# We can substring this with above split index
[PSCustomObject]@{
Name = $user.Substring(0, $splitIndex).Trim()
Email = $user.Substring($splitIndex + 1).Trim('<', '>')
}
}
} | Export-Csv -Path .\sample.csv -NoTypeInformation
运行@Bacon Bits提供的以下命令:
$content = Get-content -Path 'C:\.....txt'
$content -split ';' |
Where-Object { -not [string]::IsNullOrWhiteSpace($_) } |
ForEach-Object {
if ($_ -match '\s*(?<Name>.*?)\s*<(?<Email>.*)>\s*') {
[PSCustomObject]@{Name = $Matches['Name']; Email = $Matches['Email'] }
}
else {
Write-Warning "Unrecognized name and email in '$_'"
}
} | Export-Csv -Path 'C:\.....csv' -NoTypeInformation
很多很棒的答案。我想添加另一个选项
$content = "Doe, John L (Male) <JohnD@email.com>; Smith, Jane M (Female) <JaneS@email.com>;"
switch -Regex ($content -split ';'){
'\s?(.+)\s<(.+)>' {
[PSCustomObject]@{
Name = $Matches.1
Email = $Matches.2
}
}
}
要导出csv,只需将输出捕获到一个变量,或者可以使用子表达式将其包围,然后使用管道
$content = "Doe, John L (Male) <JohnD@email.com>; Smith, Jane M (Female) <JaneS@email.com>;"
$output = switch -Regex ($content -split ';'){
'\s?(.+)\s<(.+)>' {
[PSCustomObject]@{
Name = $Matches.1
Email = $Matches.2
}
}
}
$output | Export-Csv $outputfile -NoTypeInformation
或
文本文件中是否只有一行,或者信息被拆分为多行?不幸的是,只有一行。这样做很好,但在运行itI时留下了<或>,我想我错过了一次编辑,因为内容是复制/粘贴的。我改变了答案。很好的正则表达式示例,这很有效!另一个很好的正则表达式示例,我很欣赏它的分解和添加的警告功能。非常感谢。
$content = "Doe, John L (Male) <JohnD@email.com>; Smith, Jane M (Female) <JaneS@email.com>;"
switch -Regex ($content -split ';'){
'\s?(.+)\s<(.+)>' {
[PSCustomObject]@{
Name = $Matches.1
Email = $Matches.2
}
}
}
Name Email
---- -----
Doe, John L (Male) JohnD@email.com
Smith, Jane M (Female) JaneS@email.com
$content = "Doe, John L (Male) <JohnD@email.com>; Smith, Jane M (Female) <JaneS@email.com>;"
$output = switch -Regex ($content -split ';'){
'\s?(.+)\s<(.+)>' {
[PSCustomObject]@{
Name = $Matches.1
Email = $Matches.2
}
}
}
$output | Export-Csv $outputfile -NoTypeInformation
$content = "Doe, John L (Male) <JohnD@email.com>; Smith, Jane M (Female) <JaneS@email.com>;"
$(switch -Regex ($content -split ';'){
'\s?(.+)\s<(.+)>' {
[PSCustomObject]@{
Name = $Matches.1
Email = $Matches.2
}
}
}) | Export-Csv $outputfile -NoTypeInformation