使用正则表达式解析EML文本

时间:2015-07-21 06:38:54

标签: regex parsing powershell eml email-parsing

你能帮帮我吗,请用正则表达式解析EML文本。

我想分开:

1)。 Content-Transfer-Encoding:base64和 - = _替代之间的文本,如果有以上行Content-Type:text / html

2)。 Content-Transfer-Encoding:base64和 - = _之间的文本相关,如果行上面有两行Content-Type:image / jpeg

请关注powershell中代码的和平:

$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})
    }
}

感谢您的帮助。祝你有愉快的一天。

P.S。基于Jessie Westlake的代码,这里是RegEx的一个小编辑版本,对我有用:

    post:
      consumes:
        - application/json
      produces:
        - application/json
        - text/xml
        - text/html
      parameters:
        - name: body
          in: body
          required: true
          schema:
            # Body schema with atomic property examples
            type: object
            properties:
              testapi:
                type: object
                properties:
                  messageId:
                    type: string
                    example: kkkk8
                  messageDateTime:
                    type: string
                    example: '2014-08-17T14:07:30+0530'
              testapiBody:
                type: object
                properties:
                  cameraServiceRq:
                    type: object
                    properties:
                      osType:
                        type: string
                        example: android
                      deviceType:
                        type: string
                        example: samsung555
            # Alternatively, we can use a schema-level example
            example:
              testapi:
                testapiContext:
                  messageId: kkkk8
                  messageDateTime: '2014-08-17T14:07:30+0530'
                testapiBody:
                  cameraServiceRq:
                    osType: android
                    deviceType: samsung555

1 个答案:

答案 0 :(得分:1)

TL; DR :只需转到底部的代码......

以下代码非常难看,请原谅我。

基本上我只是创建了一个与Content-Type: text/html匹配的正则表达式。它会跟随之后的所有内容进行匹配,直到它遇到换行符\n,回车\r或一个接一个\r\n的组合。

您必须将它们包含在括号中才能使用或|运算符。我们不想实际捕获/返回任何这些组,因此我们使用(?:text-to-match)的非捕获组语法。我们可以在其他地方使用它。您也可以将捕获和非捕获组放在彼此内部。

无论如何,继续。匹配新行后,我们希望看到Content-Transfer-Encoding: base64。这似乎是每个例子中都需要的。

之后我们想要识别下一个换行符,就像上次一样。除此之外,我们希望使用+匹配1个或更多。我们需要匹配多个的原因是,您希望保存的数据似乎有一个额外的行。但是,由于有时它不会有一个额外的线,我们需要使它'懒惰&#34;使用带有问号+?的加号。

之后是我们将捕获您的实际数据的部分。这将是我们第一次使用实际捕获组,而非非捕获组(即没有问号后跟冒号)。

我们希望捕获任何不是新行的内容,因为有时候您的数据后面会跟一个新行,有时候不会。通过不允许自己捕获任何新行,它还将迫使我们的前一组人员吞噬我们数据之前的任何额外新行。捕获组是([^(?:\n|\n\r)]+)

我们在那里做的是将正则表达式包装在括号中以便捕获它。我们将表达式放在括号内,因为我们想要创建自己的&#34;类&#34;的人物。括号内的任何字符都将是我们的代码所寻找的。与我们的不同之处在于,我们将一个克拉^作为括号内的第一个字符。这意味着不是任何这些角色。显然我们希望匹配所有内容直到下一行,所以我们希望尽可能多次捕获任何非换行符,一次或多次。

然后我们确保我们的正则表达式锚定到一些结束文本,所以我们一直在尝试匹配。从另一个与至少一个匹配的换行符开始,但只需要使我们的捕获成功(?:\n|\r|\r\n)+?

最后,我们坚持我们所知道的,我们可以停止寻找我们的重要数据。这就是--=_。我不确定我们是否会偶然发现一个&#34;替代品#34;单词或&#34;相关&#34;,所以我没有走那么远。现在已经完成了。

全部的关键

如果我们没有添加正则表达式&#34; SingleLine&#34;我们将无法匹配新行。模式。为了实现这一点,我们必须使用.NET语言来创建匹配。我们从[System.Text.RegularExpressions.RegexOptions]类型输入加速。选项是&#34; SingleLine&#34;和&#34; MultiLine&#34;。

我为text/htmlimage/jpeg搜索创建了单独的正则表达式。我们将这些匹配的结果保存到各自的变量中。

我们可以通过索引到0索引来测试匹配的成功,该索引将包含整个匹配对象并访问其.success属性,该属性返回一个布尔值。可以使用.count属性访问匹配计数。为了访问特定的组和捕获,我们必须在找到适当的捕获组索引后点到它们中。由于我们只使用一个捕获组而其余的都是非捕获组,因此我们将为整个文本匹配设置[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