【问题标题】:Find all matches in a string from list of possibilities in array从数组中的可能性列表中查找字符串中的所有匹配项
【发布时间】:2018-04-12 17:59:39
【问题描述】:

我有一封电子邮件的正文(此时在代码中,它只是一个字符串),以及我需要查找的一组单词。我正在尝试从单词数组中获取电子邮件中的单词数组。例如:

$wordsArray = "foo|bar|regex|powershell"
$emailBody = "This is an email body written into a string, without breaks. foo regex."

我希望从中收到

@("foo", "regex")

大小写无关紧要,顺序无关紧要,等等。

现在我有这个功能:

function func($emailBody, $wordsArray) {
    $matched= @()
    $matched+= $emailBody| Select-String $wordsArray -AllMatches | ForEach-Object { $_.Matches.Value }

    return $matched | sort -Unique

}

但是,此功能以惊人的速度增长。我循环了多封电子邮件,第一次运行它是 0.05287 秒,第 30 次运行是 0.11733 秒,第 45 次运行是 1.72352 秒,第 50 次运行超过 5 秒。我必须运行 40,000 次(并且还在增长)。

有什么建议吗?

【问题讨论】:

  • 您可以包含其余代码吗?我不明白为什么您发布的函数的运行时间会在多次使用时增加。
  • @ctwheels 我没有与任何网络邮件对象交互,在脚本的这一点上,它是一个原始字符串。你可以用“randomString”完全替换“email”,我也会有同样的问题。
  • @AxelPersinger 将该信息添加到您的问题中以防止进一步混淆

标签: arrays regex powershell


【解决方案1】:

看看这是否不会加快进程:

$wordsFound = @{}
filter AddWord { $wordsFound[$_]++ }
$wordsArray = @("foo", "bar", "regex", "powershell")
$regex = ‘(?i)^(‘ + (($wordsArray |foreach {[regex]::escape($_)}) –join “|”) + ‘)$’

$emailBody = "This is an email, without breaks. foo regex."
$emailBody -split '\W' -match $regex | AddWord

$wordsFound.getenunumerator().Name | sort

这会从您的单词数组创建一个交替的正则表达式,然后在单词边界处拆分电子邮件正文,在电子邮件中创建一个单词数组,并将其与正则表达式匹配。由于您使用 -match 作为数组运算符,它将充当过滤器,在单个操作中传递与正则表达式匹配的所有单词。

编辑:添加了一个使用哈希表作为流内重复数据删除机制的示例。

【讨论】:

  • 它把时间缩短了一半,但它仍然呈指数增长。这对我来说毫无意义,但它肯定会在没有相应的体型增长的情况下增长
  • 您的内存消耗情况如何?您是否在对所有电子邮件进行重复数据删除操作之前积累了所有电子邮件中的所有单词?如果该数组变得越来越大,它可能会占用您的内存管理,并且您可能会使用哈希表在流中对它们进行重复数据删除。我会用一个例子来更新答案。
  • 电子邮件字符串实际上来自一个相当大的 SharePoint 对象列表,我只是将字符串传递给此函数。我监控了内存消耗,没有看到任何重大的峰值或任何东西。不幸的是,我尝试了您的编辑,但似乎没有任何改进。 @mjolinor
  • 关于我目前唯一的建议是开始在流程的各个点添加一些测量命令行,看看它们是否会告诉您瓶颈在哪里发展。
猜你喜欢
  • 2019-03-10
  • 2020-08-07
  • 2023-01-06
  • 2015-11-17
  • 2017-11-14
  • 2013-03-19
  • 2019-07-21
  • 2017-04-15
  • 1970-01-01
相关资源
最近更新 更多