0

EML テキストを正規表現で解析してください。

個別に取得したい:

1)。Content-Transfer-Encoding: base64 と --=_alternative の間のテキスト、Content-Type: text/html の行の上にある場合

2)。Content-Transfer-Encoding: base64 と --=_related の間のテキスト、その上に 2 行ある場合 Content-Type: image/jpeg

powershell でのコードの平和について見てください。

$text = @"
--=_alternative XXXXXXXXXXXXXX_=
Content-Type: text/html; charset="KOI8-R"
Content-Transfer-Encoding: base64

111111111111111111111111111111111111111111111111111111

--=_alternative XXXXXXXXXXXXXX_=
Content-Type: text/html; charset="KOI8-R"
Content-Transfer-Encoding: base64

222222222222222222222222222222222222222222222222222222
--=_alternative XXXXXXXXXXXXXX_=--
--=_related XXXXXXXXXXXXXX_=--_=
Content-Type: image/jpeg
Content-ID: <_2_XXXXXXXXXXXXXX>
Content-Transfer-Encoding: base64

333333333333333333333333333333333333333333333333333333
--=_related XXXXXXXXXXXXXX_=
Content-Type: image/jpeg
Content-ID: <_2_XXXXXXXXXXXXXX>
Content-Transfer-Encoding: base64
444444444444444444444444444444444444444444444444444444

--=_related XXXXXXXXXXXXXX_=
Content-Type: image/jpeg
Content-ID: <_2_XXXXXXXXXXXXXX>
Content-Transfer-Encoding: base64

555555555555555555555555555555555555555555555555555555
--=_related XXXXXXXXXXXXXX_=--
"@

$regex1 = "(?ms).+?Content-Transfer-Encoding: base64(.+?)--=_alternative"
$text1 = ([regex]::Matches($text,$regex1) | foreach {$_.groups[1].value})
Write-Host "text1 : " -fore red
Write-Host  $text1

#I want to get as output elements (of array, maybe, or one after another)
#1). text between  Content-Transfer-Encoding: base64 and --=_alternative, if there is above line Content-Type: text/html
#this
#1111111111111111111111111111111111111111111111111111111
#then this
#2222222222222222222222222222222222222222222222222222222

$regex2 = "(?ms).+?Content-Transfer-Encoding: base64(.+?)--=_related"
$text2 = ([regex]::Matches($text,$regex2) | foreach {$_.groups[1].value})
#I want to get as output elements (of array, maybe, or one after another)
#2). text between  Content-Transfer-Encoding: base64 and --=_related, if there is two lines above line Content-Type: image/jpeg
#this
#3333333333333333333333333333333333333333333333333333333
#then this
#4444444444444444444444444444444444444444444444444444444
#then this
#5555555555555555555555555555555555555555555555555555555
Write-Host "text2 : " -fore red
Write-Host  $text2

ご協力いただきありがとうございます。良い1日を。

PS Jessie Westlakeのコードに基づいて、これが私のために働いたRegExの少し編集されたバージョンです:

$files = Get-ChildItem -Path "\\<SERVER_NAME>\mailroot\Drop"
Foreach ($file in $files){
    $text = Get-Content $file.FullName

    $RegexText = '(?:Content-Type: text/html.+?Content-Transfer-Encoding: base64(.+?)(?:--=_))'
    $RegexImage = '(?:Content-Type: image/jpeg.+?Content-Transfer-Encoding: base64(.+?)(?:--=_))'

    $TextMatches = [Regex]::Matches($text, $RegexText, [System.Text.RegularExpressions.RegexOptions]::Singleline)
    $ImageMatches = [Regex]::Matches($text, $RegexImage, [System.Text.RegularExpressions.RegexOptions]::Singleline)

    If ($TextMatches[0].Success)
    {
        Write-Host "Found $($TextMatches.Count) Text Matches:"
        Write-Output $TextMatches.ForEach({$_.Groups[1].Value})
    }
    If ($ImageMatches[0].Success)
    {
        Write-Host "Found $($ImageMatches.Count) Image Matches:"
        Write-Output $ImageMatches.ForEach({$_.Groups[1].Value})
    }
}
4

1 に答える 1

1

TL;DR : 下部のコードに移動してください...

以下のコードはかなり醜いので、ご容赦ください。

基本的に、 で始まる一致する正規表現を作成しただけですContent-Type: text/html\nそれ以降は、改行、改行\r、または次々との組み合わせに到達するまで遅延して一致します\r\n

|or演算子を使用するには、それらを括弧で囲む必要があります。これらのグループを実際にキャプチャして返したくないので、 の非キャプチャ グループ構文を使用します(?:text-to-match)。ご覧のとおり、これを別の場所で使用しています。キャプチャ グループと非キャプチャ グループを互いの内部に配置することもできます。

とにかく、続けます。新しい行を一致させた後、見たいですContent-Transfer-Encoding: base64。それはあなたの各例で必要なようです。

その後、前回と同じように、次の改行を識別したいと考えています。今回を除いて、+. 複数の一致が必要な理由は、保存したいデータの前に余分な行がある場合があるためです。ただし、前に追加の行がない場合があるため、プラスの後に疑問符を付けて「怠惰」にする必要があります+?

その後、実際のデータをキャプチャする部分が続きます。非キャプチャ グループ (つまり、疑問符の後にコロンが続く) ではなく、実際のキャプチャ グループを使用するのはこれが初めてです。

データの後に改行が続く場合とそうでない場合があるため、改行ではないものをすべてキャプチャしたいと考えています。新しい行をキャプチャできないようにすることで、前のグループがデータの前にある余分な新しい行をむさぼり食うようになります。その捕獲グループは([^(?:\n|\n\r)]+)

そこで行っていたのは、正規表現をキャプチャするために括弧で囲んだことです。文字の独自の「クラス」を作成するため、式を括弧内に配置します。括弧内の文字はすべて、コードが探しているものになります。^ただし、私たちのものとの違いは、括弧内の最初の文字としてカラットを入れることです. つまり、これらの文字のいずれでもないことを意味します。明らかに、次の行まですべてを一致させたいので、改行以外のものを 1 回以上、可能な限り何度でもキャプチャしたいと考えています。

次に、正規表現が末尾のテキストに固定されていることを確認して、一致を試み続けます。少なくとも 1 つ一致する別の改行から始めますが、キャプチャを成功させるために必要な数は少なくします(?:\n|\r|\r\n)+?

最後に、重要なデータを探すのをやめる場所になることが確実にわかっているものに固定します。そして、それは--=_です。「代替」または「関連」という単語に出くわすかどうかわからなかったので、そこまでは行きませんでした。これで完了です。

すべての鍵

正規表現の「SingleLine」モードを追加しないと、改行を介して一致することはできません。これを有効にするには、.NET 言語を使用して一致を作成する必要があります。タイプから加速して[System.Text.RegularExpressions.RegexOptions]いきます。オプションは「SingleLine」と「MultiLine」です。

text/htmlおよびimage/jpeg検索用に別の正規表現を作成します。これらの一致の結果をそれぞれの変数に保存します。

一致オブジェクト全体を含む 0 インデックスにインデックスを付け.success、ブール値を返すそのプロパティにアクセスすることで、一致の成功をテストできます。一致の数は、.countプロパティでアクセスできます。特定のグループとキャプチャにアクセスするには、適切なキャプチャ グループ インデックスを見つけた後、それらにドット記法を適用する必要があります。キャプチャ グループを 1 つだけ使用し、残りは非キャプチャであるため、テキスト一致全体の [0] インデックスがあり、[1] にはキャプチャ グループの一致が含まれている必要があります。オブジェクトなので、value プロパティにアクセスする必要があります。

明らかに、以下のコードでは、 $text 変数に検索するデータが含まれている必要があります。

$RegexText = '(?:Content-Type: text/html.+?(?:\n|\r|\r\n)Content-Transfer-Encoding: base64(?:\n|\r|\r\n)+?([^(?:\n|\n\r)]+)(?:\n|\r|\r\n)+?(?:\n|\r|\r\n)(?:--=_))'
$RegexImage = '(?:Content-Type: image/jpeg.+?(?:\n|\r|\r\n)Content-Transfer-Encoding: base64(?:\n|\r|\r\n)+?([^(?:\n|\n\r)]+)(?:\n|\r|\r\n)+?(?:\n|\r|\r\n)(?:--=_))'

$TextMatches = [Regex]::Matches($text, $RegexText, [System.Text.RegularExpressions.RegexOptions]::Singleline)
$ImageMatches = [Regex]::Matches($text, $RegexImage, [System.Text.RegularExpressions.RegexOptions]::Singleline)

If ($TextMatches[0].Success)
{
    Write-Host "Found $($TextMatches.Count) Text Matches:"
    Write-Output $TextMatches.ForEach({$_.Groups[1].Value})
}
If ($ImageMatches[0].Success)
{
    Write-Host "Found $($ImageMatches.Count) Image Matches:"
    Write-Output $ImageMatches.ForEach({$_.Groups[1].Value})
}

上記のコードを実行すると、画面に次の出力が表示されます。

Found 2 Text Matches:
111111111111111111111111111111111111111111111111111111
222222222222222222222222222222222222222222222222222222
Found 3 Image Matches:
333333333333333333333333333333333333333333333333333333
444444444444444444444444444444444444444444444444444444
555555555555555555555555555555555555555555555555555555
于 2015-07-21T08:23:58.770 に答える