powershell 从正文中获取特定行
powershell get specific row from a body
我在从 Powershell 主体获取特定行时遇到了一些问题。人力资源团队向我们发送电子邮件,逻辑应用程序获取电子邮件正文并将其传递给禁用用户的脚本。
身材是这样的:
Hi,
the following user have to be dismiss:
#mail: user1@mycompany.com
#mail: user2@mycompany.com
#mail: user2@mycompany.com
Bye
hr team
hrteam@mycompany.com
我只想获取特定行:
#mail: user1@mycompany.com
#mail: user2@mycompany.com
#mail: user2@mycompany.com
为此,我使用以下代码做了一个小技巧:
$Body
$SplitBody = $Body.split("").split(" ").Split("#")
$objetbody = $SplitBody.Replace(" ","").Trim()
我得到了以下结果:
Hi,
the
following
user
have
to
be
dismiss:
mail:
user1@mycompany.com
mail:
user2@mycompany.com
mail:
user2@mycompany.com
Bye
hr
team
hrteam@mycompany.com
之后,我将 $objetbody 传递到一个 foreach 并循环所有行(在此 foreach 的末尾放置一个中断,因为它可以禁用 HR 邮件)。如果 HR 仅发送 1 封邮件以禁用,则流程有效。
我的问题是有没有办法获取包含邮件的特定行?
谢谢
除了 -match
operator and the use of the automatic variable $Matches
之外,您还可以使用循环:
foreach($line in $Body)
{
if($line -match '^#mail: (.*@.*\.[\w\d]+)')
{
$Matches[1]
}
}
在上面的示例中,$Matches[1]
将 return 匹配捕获组的值:
user1@mycompany.com
user2@mycompany.com
user2@mycompany.com
如果您想保留 #mail:
,请改用 $Matches[0]
。
这里是 one-liner 使用 .NET RegEx class:
输出所有电子邮件地址
[RegEx]::Matches( $body, '(?<=#mail:\s*)\S+' ).Value
同样可以使用 Select-String
:
($body | Select-String '(?<=#mail:\s*)\S+' -AllMatches).Matches.Value
正则表达式细分:
(?<=
... 开始对模式进行正向查找,这意味着我们搜索的子字符串前面必须有给定的模式,但该模式不会包含在结果中
#mail:\s*
... 文字“#mail:”后跟可选的空格
)
... 结束后视模式
\S+
...任何 non-whitespace 个字符的序列 -> 电子邮件地址
我保持电子邮件地址模式简单,因为 matching email addresses using RegEx can be hard. Anyway you propably want to do validation as a separate step so you can report invalid addresses. This can be done much simpler using the .NET MailAddress
class:
$mailAddresses = [RegEx]::Matches( $body, '(?<=#mail:\s*)\S+' ).Value
foreach( $adr in $mailAddresses) {
try {
[System.Net.Mail.MailAddress]::new( $adr )
} catch {
# The MailAddress constructor throws FormatException for invalid address
Write-Error "Invalid mail address: '$adr'"
}
}
我在从 Powershell 主体获取特定行时遇到了一些问题。人力资源团队向我们发送电子邮件,逻辑应用程序获取电子邮件正文并将其传递给禁用用户的脚本。
身材是这样的:
Hi,
the following user have to be dismiss:
#mail: user1@mycompany.com
#mail: user2@mycompany.com
#mail: user2@mycompany.com
Bye
hr team
hrteam@mycompany.com
我只想获取特定行:
#mail: user1@mycompany.com
#mail: user2@mycompany.com
#mail: user2@mycompany.com
为此,我使用以下代码做了一个小技巧:
$Body
$SplitBody = $Body.split("").split(" ").Split("#")
$objetbody = $SplitBody.Replace(" ","").Trim()
我得到了以下结果:
Hi,
the
following
user
have
to
be
dismiss:
mail:
user1@mycompany.com
mail:
user2@mycompany.com
mail:
user2@mycompany.com
Bye
hr
team
hrteam@mycompany.com
之后,我将 $objetbody 传递到一个 foreach 并循环所有行(在此 foreach 的末尾放置一个中断,因为它可以禁用 HR 邮件)。如果 HR 仅发送 1 封邮件以禁用,则流程有效。
我的问题是有没有办法获取包含邮件的特定行?
谢谢
除了 -match
operator and the use of the automatic variable $Matches
之外,您还可以使用循环:
foreach($line in $Body)
{
if($line -match '^#mail: (.*@.*\.[\w\d]+)')
{
$Matches[1]
}
}
在上面的示例中,$Matches[1]
将 return 匹配捕获组的值:
user1@mycompany.com
user2@mycompany.com
user2@mycompany.com
如果您想保留 #mail:
,请改用 $Matches[0]
。
这里是 one-liner 使用 .NET RegEx class:
输出所有电子邮件地址[RegEx]::Matches( $body, '(?<=#mail:\s*)\S+' ).Value
同样可以使用 Select-String
:
($body | Select-String '(?<=#mail:\s*)\S+' -AllMatches).Matches.Value
正则表达式细分:
(?<=
... 开始对模式进行正向查找,这意味着我们搜索的子字符串前面必须有给定的模式,但该模式不会包含在结果中#mail:\s*
... 文字“#mail:”后跟可选的空格
)
... 结束后视模式\S+
...任何 non-whitespace 个字符的序列 -> 电子邮件地址
我保持电子邮件地址模式简单,因为 matching email addresses using RegEx can be hard. Anyway you propably want to do validation as a separate step so you can report invalid addresses. This can be done much simpler using the .NET MailAddress
class:
$mailAddresses = [RegEx]::Matches( $body, '(?<=#mail:\s*)\S+' ).Value
foreach( $adr in $mailAddresses) {
try {
[System.Net.Mail.MailAddress]::new( $adr )
} catch {
# The MailAddress constructor throws FormatException for invalid address
Write-Error "Invalid mail address: '$adr'"
}
}