簡體   English   中英

VB.Net正則表達式獲取字符串

[英]VB.Net Regex to get string

我有這個String,我只想獲取包含真實電子郵件但沒有HTML標簽的部分。 標記為(此行)

    Content-Type: multipart/alternative; boundary=001a11391134f9593b05083dbd67
    X-Antivirus: avast! (VPS 141119-1, 19/11/2014), Inbound message
    X-Antivirus-Status: Clean

    --001a11391134f9593b05083dbd67
    Content-Type: text/plain; charset=UTF-8

    (this lines) lorem ipsum (this lines)
    (this lines) dolor sit amet (this lines)

    --001a11391134f9593b05083dbd67
    Content-Type: text/html; charset=UTF-8

    <div dir="ltr">lorem ipsum dolor sit amet</div>

    --001a11391134f9593b05083dbd67--
    .

我認為正則表達式類似於^ Content-Type:text / plain。*。?$ (直到找到兩個“-”),但我不知道該怎么做。

謝謝!

我不是regex專家,所以我可能會誤解術語,但這應該找到直到下一個匹配邊界( \\1匹配第一個捕獲組)的text/plain內容:

Dim content As String ' your string
Dim match = Regex.Match(
    content,
    "(\n--[0-9a-f]+)\nContent-Type: text/plain.*?\n\n(.*?)\1",
    RegexOptions.Multiline Or RegexOptions.Singleline
)
Dim textContent = match.Groups(2).Value

您可能需要一些錯誤處理(可能使用Regex.Matches代替),並且可能需要為實際內容調整一些內容。

更新資料

這是粘貼到LINQPad中的完整代碼:

Dim content = <![CDATA[Content-Type: multipart/alternative; boundary=001a11391134f9593b05083dbd67
X-Antivirus: avast! (VPS 141119-1, 19/11/2014), Inbound message
X-Antivirus-Status: Clean

--001a11391134f9593b05083dbd67
Content-Type: text/plain; charset=UTF-8

(this lines) lorem ipsum (this lines)
(this lines) dolor sit amet (this lines)

--001a11391134f9593b05083dbd67
Content-Type: text/html; charset=UTF-8

<div dir="ltr">lorem ipsum dolor sit amet</div>

--001a11391134f9593b05083dbd67--
.]]>.Value

Dim match = RegEx.Match(content, "(\n--[0-9a-f]+)\nContent-Type: text/plain.*?\n\n(.*?)\1", RegexOptions.Multiline Or RegexOptions.Singleline)
Console.WriteLine("** Start **")
match.Groups(2).Value.Dump
Console.WriteLine("** End **")

這是輸出-我添加了開始和結束以顯示空白行也已捕獲:

** Start **
(this lines) lorem ipsum (this lines)
(this lines) dolor sit amet (this lines)

** End **

在我在我的評論中提供的表達式周圍玩耍之后,看起來非捕獲組仍包含在比賽中,因此:

Dim match As Match = Regex.Match(input, "(Content-Type: text/plain; charset=UTF-8\s+)((?!\s+--).|\n)*")
Dim result As String = match.Groups(0).Value.Replace(match.Groups(1).Value, "")

不幸的是,它不像直接表達式匹配那么干凈,但是應該返回您要查找的結果。 如果要保留左邊緣間距(如您的示例所示),請使用以下表達式:

(Content-Type: text/plain; charset=UTF-8)((?!\s+--).|\n)*

RegEx不會擅長於此。 您需要做的是找到邊界說明符,並使用該說明符找到所需的部分。

“直到找到兩個-”注定要失敗,因為“短划線返回”用於指示后面的簽名,郵件客戶端不應在回復中包括該簽名。 盡管我懷疑這在90年代迷失了。 無論如何,有人在電子郵件中使用“-”並不罕見。

以下是未精煉的代碼,它們僅找到第一部分。 您只需要檢查找到的數據的第一行,然后檢查它是否是您想要的(可能是Content-Type: text/plain; charset=UTF-8或其他可能需要使用的字符集)。 如果沒有,請嘗試下一部分:

Option Infer On

Imports System.IO

Module Module1

    Function GetBoundarySpecifier(s As String()) As String
        Dim boundarySpecifier = ""

        Dim boundarySpecifierMarker = "Content-Type: multipart/alternative; boundary="
        For i = 0 To s.Length - 1
            If s(i).StartsWith(boundarySpecifierMarker, StringComparison.InvariantCultureIgnoreCase) Then
                ' N.B. the boundary specifier may be enclosed in double-quotes - RFC 2046 section 5.1.1
                boundarySpecifier = s(i).Substring(boundarySpecifierMarker.Length).Trim(""""c)
            End If
        Next
        Return boundarySpecifier
    End Function

    Function LineIndex(stringToInspect As String(), soughtString As String, startIndex As Integer) As Integer
        ' find the first line starting at startIndex which matches the sought string
        For i = startIndex To stringToInspect.Length - 1
            If stringToInspect(i) = soughtString Then
                Return i
            End If
        Next

        Return -1

    End Function

    Sub Main()
        ' the sample data is stored in a text file for this example:
        Dim srcFile = "C:\temp\sampleEmail.txt"

        ' RFC 2821 section 2.3.7 specifies that lines end with CRLF
        Dim srcData = File.ReadAllLines(srcFile)

        Dim boundarySpecifier = GetBoundarySpecifier(srcData)

        If boundarySpecifier.Length > 0 Then
            boundarySpecifier = "--" & boundarySpecifier
            Dim idx1 = LineIndex(srcData, boundarySpecifier, 0)
            Dim idx2 = LineIndex(srcData, boundarySpecifier, idx1 + 1)
            Dim messageData = srcData.Skip(idx1 + 1).Take(idx2 - idx1 - 1)

            Console.WriteLine(String.Join(vbCrLf, messageData))
            Console.WriteLine("--end--")
        Else
            Console.WriteLine("Did not find the part.")
        End If

        Console.ReadLine()

    End Sub

End Module

輸出:

Content-Type: text/plain; charset=UTF-8

(this lines) lorem ipsum (this lines)
(this lines) dolor sit amet (this lines)

--end--

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM