【问题标题】:Regular expression to parse Final-Recipient email header解析 Final-Recipient 电子邮件标头的正则表达式
【发布时间】:2019-08-15 15:27:34
【问题描述】:

我必须得到以下之间的任何文本:

最终接收者:RFC822; !这里!行动

我需要此示例中的 !HERE!。可以有任何字符串。

我尝试了类似的方法:

$Pattern = '/Final-Recipient: RFC822; (.*) Action/';

但它不起作用。

更新

这是我要解析的字符串:http://dpaste.com/187638/

【问题讨论】:

  • 如何定义 !HERE! 的结尾?总是用感叹号吗?
  • 需要文字后跟'Action/'
  • 斜线不在您的原始帖子中
  • @Ockonal 我的字符串不好。谢谢!已删除答案。
  • 嗯,正则表达式需要斜线。原文为:Final-Recipient: RFC822; ...行动

标签: php regex


【解决方案1】:

由于您说“任何字符串”可能包含空格,因此最接近的近似值是

$Pattern = '/Final-Recipient: RFC822; (.*?) Action/s';
#                                        ^         ^
# lazy match instead of greedy match ----'         |
#                    allow . to match newline -----'

当然不会匹配"Final-Recipient: RFC822; Action Action"

【讨论】:

  • 请看更新。此正则表达式不适用于给定的文本。
【解决方案2】:

你的模式很适合我:

$i = 'This is a MIME-encapsulated message --o3ONXoEH01blah3:35:33 +0400 (MSD) Final-Recipient: RFC822; !HERE! Action: failed Status: 4.4.7 Lblahru> From: *
@*.ru';    
$pattern = '/Final-Recipient: RFC822; (.*) Action/';
$matches = Array();
preg_match($pattern, $i, $matches);
print_r($matches);

输出:

Array
(
    [0] => Final-Recipient: RFC822; !HERE! Action
    [1] => !HERE!
)

还要注意,如果“任何文本”包含新行,您的模式将失败。使用DOTALL modifier /.../s 允许点也匹配新行。另请注意,如果文本“Action”出现在消息中的其他位置,则会导致您的正则表达式失败。匹配点是危险的。如果可能,尝试找到更具体的模式。

【讨论】:

  • 说实话,可能只有电子邮件地址。任何换行符。
【解决方案3】:
$Pattern = '/Final-Recipient:[^;]+[;|<|\s]+([^\s|^<|^>]+)/i';

事实证明,以下表达式最适合我的问题,因为有时会有以下类型的行:

Final-Recipient: LOCAL;<example@rambler.ru>

【讨论】:

    【解决方案4】:

    我将建议一种不使用它们的方法,这需要额外的工作。

    <?php
    $message = 'This is a MIME-encapsulated message --o3ONXoEH016763.1272152184/zvm19.host.ru The original message was received at Fri, 23 Apr 2010 03:35:33 +0400 (MSD) from roller@localhost ----- The following addresses had permanent fatal errors ----- "Flucker" ----- Transcript of session follows ----- 451 grl.unibel.by: Name server timeout Message could not be delivered for 2 days Message will be deleted from queue --o3ONXoEH016763.1272152184/*.host.ru Content-Type: message/delivery-status Reporting-MTA: dns; zvm19.host.ru Arrival-Date: Fri, 23 Apr 2010 03:35:33 +0400 (MSD) Final-Recipient: RFC822; !HERE! Action: failed Status: 4.4.7 Last-Attempt-Date: Sun, 25 Apr 2010 03:36:24 +0400 (MSD) --o3ONXoEH016763.1272152184/zvm19.host.ru Content-Type: message/rfc822 Content-Transfer-Encoding: 8bit Return-Path: Received: (from *@localhost) by *.host.ru (8.13.8/Zenon/Postman) id o3MNZX5h059932; Fri, 23 Apr 2010 03:35:33 +0400 (MSD) (envelope-from *@roller.ru) Date: Fri, 23 Apr 2010 03:35:33 +0400 (MSD) Message-Id: <201004222335.o3MNZX5h059932@*.host.ru> From: *
    @*.ru';
    $left_delimiter = 'Final-Recipient: RFC822; ';
    $right_delimiter = ' Action';
    $left_delimiter_pos = strrpos($message, $left_delimiter);
    $right_delimiter_pos = strpos($message, $right_delimiter);
    $desired_message_fragment = '';
    if ($left_delimiter_pos !== false && $right_delimiter_pos !== false) {
        $fragment_start = $left_delimiter_pos + strlen($left_delimiter);
        $fragment_length = $right_delimiter_pos - $fragment_start;
        $desired_message_fragment = substr(
            $message, $fragment_start, $fragment_length
        );
    }
    var_dump($desired_message_fragment);
    

    【讨论】:

      【解决方案5】:

      有点晚了……

      但是被问到如何解决一个不是他要求的问题 Op 可能已经将多行合并到一行?(恕我直言)。

      这可能对其他人有所帮助....

      我假设 op 正在尝试解析传递状态通知的 Final-Recipient 标头字段。

      可以在此处查看 Final-Recipient 字段的规范:https://www.rfc-editor.org/rfc/rfc3464#page-15

      如果问题被分解,op 可以将最终收件人字段作为单个字段提取(最终收件人后跟下一行的字符/空白行。

      例如

      Original-recipient: rfc822;some-email-that-does-not-exist@gmail.com
      Final-recipient: rfc822;some-email-that-does-not-exist@gmail.com
      Action: failed
      Status: 5.1.1 (Remote SMTP server has rejected address)
      

      最终接收者之后是下一个字段的开始,即下一行有 A 的操作。即后面没有空格或空行。

      那么他所要做的就是将线路分开;并采取第二部分

      String[] twoparts = "Final-recipient: rfc822;some-email-that-does-not-exist@gmail.com".split(";",2) // 2 here means (2-1) = 1 match
      String email = twoparts[1]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-08-28
        • 1970-01-01
        • 1970-01-01
        • 2011-04-22
        • 2016-04-11
        • 2012-09-30
        相关资源
        最近更新 更多