2017-10-31 4 views
0

に可能性のリストから文字列内のすべての一致を検索します。私は単語の配列から電子メールにあった単語の配列を取得しようとしています。たとえば、次のように私は電子メールの本文(コードのこの時点で、それは単なる文字列です)、そして私が見つける必要がある単語の配列を持つ配列

$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回(そして成長する)走らなければなりません。

ヒント?これは、プロセススピードアップしていない場合

+0

残りのコードを含めることはできますか?あなたが投稿した機能の実行時間が複数の用途で増加する理由はわかりません。 – ConnorLSW

+0

@ctwheels私はウェブメールオブジェクトとインターフェースしていません。スクリプトのこの時点では、生の文字列です。あなたは "電子メール"を "randomString"に完全に置き換えることができ、私は同じ質問をします。 –

+0

@AxelPersingerは、さらなる混乱を避けるためにその情報をあなたの質問に追加します。 – ctwheels

答えて

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を使用しているので、フィルタとして機能し、1回の操作で正規表現に一致したすべての単語を通過します。

編集:インストリームデデュープメカニズムとしてハッシュテーブルを用いた例を追加しました。

+0

時間を半分に短縮しますが、それでも指数関数的に増加します。それは私には意味がありませんが、それはボディサイズの一致した成長なしで確実に成長しています –

+0

あなたのメモリ消費量はどのように見えますか?あなたは、それらを重複排除するような仕組みをする前に、すべての電子メールからすべての単語を集めていますか?その配列が大きくなっている場合は、メモリ管理であなたを食べている可能性があり、ハッシュテーブルを使用してストリーム内の重複をなくすことができます。答えを例で更新します。 – mjolinor

+0

電子メールの文字列は実際にはかなり大きくなるSharePointオブジェクトのリストから来ており、この関数に文字列を渡すだけです。私はmemの消費量を監視し、大きなスパイクなどは見られませんでした。私はあなたの編集を試してみましたが、残念なことに改善が見られませんでした。 @mjolinor –

関連する問題