【问题标题】:Returning the whole string when no match in a Powershell Substring(0, IndexOf)在 Powershell Substring(0, IndexOf) 中不匹配时返回整个字符串
【发布时间】:2019-07-14 02:16:33
【问题描述】:

我有一些适用于 Outlook 文件夹中邮件的 Powershell。大多数电子邮件都有一个以文本"------" 开头的页脚。我想转储此字符串之后的所有文本。

我在Select-Object 中添加了如下表达式:

$cleanser = {($_.Body).Substring(0, ($_.Body).IndexOf("------"))}
$someObj | Select-Object -Property @{ Name = 'Body'; Expression = $cleanser}

这在 IndexOf() 返回匹配时有效...但是当没有匹配时我的 Select-Object 输出 null

IndexOf 返回null 时,如何更新我的表达式以返回原始字符串?

【问题讨论】:

  • ($_.Body) -replace '(?s)------.*'

标签: powershell powershell-5.0


【解决方案1】:

PetSerAl,就像以前无数次一样,在对该问题的评论中提供了关键指针:

使用 PowerShell 的-replace operator,它实现了基于正则表达式的字符串替换,如果正则表达式不匹配,则返回输入字符串原样

# The script block to use in a calculated property with Select-Object later.
$cleanser = { $_.Body -replace '(?s)------.*' }

如果你想确保------ 只匹配一行的开始,使用(?sm)^------.*;如果您还想删除前面的换行符,请使用(?s)\r?\n------.*

  • (?s) 是一个内联正则表达式选项,它使. 也匹配换行符,因此.* 有效地匹配所有剩余的文本,跨行。

  • 通过不指定替换操作数,隐含''(空字符串),它有效地删除输入字符串中的匹配部分(技术上,删除匹配部分的原始字符串的 /em> 被返回)。

  • 如果正则表达式'(?s)------.*' 匹配,$_.Body 按原样返回(从技术上讲,返回的是输入字符串本身,而不是副本)。

最终效果是删除以------ 开头的所有内容,如果存在

【讨论】:

  • 很高兴听到它有帮助,@Adam;我的荣幸。
【解决方案2】:

我同意@mklement0 和@PetSerAl 正则表达式给出了最好的答案。耶!正则表达式的救援!

编辑: 修复我原来的帖子。

按照@Adam 在表达式中使用脚本块的想法,您只需在脚本块中添加更多逻辑以在使用前先检查索引:

$cleanser = {
    $index = ($_.Body).IndexOf("------");
    if($index -eq -1){
        $index = $_.Body.Length
    };
    ($_.Body).Substring(0, $index)
}

$someObj | Select-Object -Property @{ Name = 'Body'; Expression = $cleanser}

【讨论】:

  • @MathiasR.Jessen,问题不在于$_.Body 不是字符串——HAL9256 已解决的问题在于$_.Body.IndexOf("------") 仅被调用一次,在用作计算属性一部分的$cleanser 脚本块之外。
  • 谢谢。我更喜欢不那么冗长的答案,并且我怀疑(尽管尚未测试)它也可能更具性能。无论如何谢谢:-)
猜你喜欢
  • 2021-01-09
  • 1970-01-01
  • 2021-12-07
  • 2018-12-11
  • 2010-10-13
  • 2011-06-13
  • 2021-12-06
  • 1970-01-01
  • 2019-09-19
相关资源
最近更新 更多