Регулярное выражение прекращает захват после пробела c# - PullRequest
1 голос
/ 08 мая 2020

Мне нужно не захватывать тело строки. Я закончил с этим регулярным выражением, но оно по-прежнему фиксирует все, что идет сразу после Subject. Мне нужно захватить данные из From, To, Cc и Subject, только не включая тело сообщения. Проблема заключается в этом шаблоне регулярного выражения Subject:\s*([\s\S]*), как мне его изменить? Я все еще новичок ie в регулярных выражениях.

Это мой шаблон регулярного выражения: @"From:\s*(\S*@\S*\.\S*)\s*To:\s*(\S*@\S*\.\S*)\s*Cc:\s*(\S*@\S*\.\S*)\s*Subject:\s*([\s\S]*)".

From:                                             trial@123.com 

To:                                               trial@123.com 

Cc:                                               trial@123.com

Subject:                                    Lorem Ipsum, Lorem Ipsum Lorem Ipsum Lorem Ipsum


 Lorem Ipsum,  


 Lorem Ipsum  


 Lorem IpsumLorem IpsumLorem IpsumLorem IpsumLorem IpsumLorem IpsumLorem Ipsum

1 Ответ

1 голос
/ 08 мая 2020

Чтобы ваше регулярное выражение работало так, как вы хотите, вам нужно сделать следующее:

  • Включить опцию Multiline для объекта Regex в вашем коде.
  • Измените эту часть регулярного выражения Subject:\s*([\s\S]*) на следующую Subject:\s*([\s\S]*?)$.

Вот рабочий пример:

string text = @"From:                                             trial@123.com 

To:                                               trial@123.com 

Cc:                                               trial@123.com

Subject:                                    Lorem Ipsum, Lorem Ipsum Lorem Ipsum 
Lorem Ipsum


 Lorem Ipsum,  


 Lorem Ipsum  


 Lorem IpsumLorem IpsumLorem IpsumLorem IpsumLorem IpsumLorem IpsumLorem Ipsum";

var regex = new Regex(
    @"From:\s*(\S*@\S*\.\S*)\s*To:\s*(\S*@\S*\.\S*)\s*Cc:\s*(\S*@\S*\.\S*)\s*Subject:\s*([\s\S]*?)$",
    RegexOptions.Multiline);

Match m in regex.Match(text));

// The first Group matches whole regex value. We skip it to show only
// matched From, To, Cc and Subject values.
foreach (Group g in m.Groups.Cast<Group>().Skip(1))
{
    Console.WriteLine(g.Value);
}

Пояснение:

  • Включив опцию Multiline, мы можем использовать символ $ для соответствия концу строки.
  • Subject:\s*([\s\S]*?)$ :
    • $ в конце этого шаблона говорит, что он должен соответствовать символам до конца строки.
    • Мы добавили ?, чтобы сделать шаблон регулярного выражения для Subject не жадным . Это значит, что шаблон Subject будет совпадать до первого символа $ (конца строки). Если вы удалите ?, вы сделаете Subject шаблон регулярного выражения жадным, и он будет соответствовать до последнего символа $.

Здесь вы можете проверьте это регулярное выражение.


@ kebbg спросил в комментарии:

один вопрос, скажем, я не хочу просто писать его в консоли, и я хочу вернуть значения из каждого совпадения. Это возможно? Например, возврат (адрес электронной почты от :.), ответный адрес электронной почты на адрес ... et c.

Вы можете создать метод, который найдет From, To, Cc и Subject значения и возвращают их из метода. Затем вы можете использовать этот метод в своем проекте:

public static EmailInfo GetEmailInfo(string emailBody)
{
    var regex = new Regex(
        @"From:\s*(\S*@\S*\.\S*)\s*To:\s*(\S*@\S*\.\S*)\s*Cc:\s*(\S*@\S*\.\S*)\s*Subject:\s*([\s\S]*?)$",
        RegexOptions.Multiline);

    Match m = regex.Match(emailBody);

    if (!m.Success)
       return null;

    return new EmailInfo
    {
        From = m.Groups[1].Value,
        To = m.Groups[2].Value,
        Cc = m.Groups[3].Value,
        Subject = m.Groups[4].Value,
    };
}

public class EmailInfo
{
    public string From { get; set; }
    public string To { get; set; }
    public string Cc { get; set; }
    public string Subject { get; set; }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...