使用 PHP,如何在较长的字符串中搜索以特定内容开头和结尾的较短字符串?

Using PHP, how to search a longer string for shorter string that begins with and ends with something specific?

我正在开发一个 PHP 票务系统,我通过管道发送电子邮件,获取他们的 HTML 并插入数据库。

我已将此行添加到我的外发电子邮件中:

## If you reply, text above this line is added to the request ##

在 Upwork 的电子邮件中看到了这种类型的东西,很容易只抓住那个唯一字符串之前的 email/html,使用:

//now, get only the stuff before our "dividing" line starts
$html = strstr($html, '## If', true) ?: $html;

无论如何,我注意到 Gmail 会自动将以下内容添加到所有电子邮件回复中:

On Fri, Jun 7, 2019 at 2:40 PM Carson Wentz<carson.wentz@gmail.com> wrote:

所以在我执行第一步以仅保留“## 如果你回复...”之前的内容后,我现在想搜索剩余的 text/html 以查看它是否具有以 [ 开头的字符串=32=] 并以 "wrote:" 结尾。如果是这样,只抓住之前的东西(类似于步骤 1)。

我找不到任何内容来清楚地解释如何在较长的字符串中搜索以某些内容开头并以特定内容结尾的较短的字符串,而不管中间是什么。我想它必须使用 REGEX?

然而,当我写这篇文章时,我才意识到很可能在某个时候有人可能会以 "On" 开始他们的回复,在这种情况下,所有内容都会被删除。呃

如果有人有任何想法可以处理,请告诉我。我考虑得更多,我可能只需要让 Gmail 包含的行出现在票务系统的所有回复中,因为我认为没有绝对的方法可以获得那个确切的字符串,因为它包含 date/time和名字信息显然总是不同的。

感谢您的宝贵时间。

您可以使用 preg_replace 和以下模式:

/^(?:On .+?> wrote:)?((\R|.)+?)## If you reply, text above this line is added to the request ##/

这可以选择匹配文字 On,然后是 body 字符串开头到 > wrote:\n 的任何字符,然后捕获所有内容,直到终止消息,包括带有 [= 的换行符16=]。

当然,您可以进一步使 header 模式更严格,但似乎不太可能有人会在 上写 On [any characters...]> wrote:\n exactly第一行,这是误报,会导致信息丢失。走严格的路线可能会遇到一些极端情况,在这种情况下,不寻常的电子邮件地址会导致漏报,并被错误地认为是 body.

的一部分

下面的示例表明,即使这个 header 出现在第一行之后的任何位置,它也会被视为 body.

的一部分

如果 On... 开始之前可能有空格,请使用 ^\s*On

<?php

$withGmailHeader = "On Fri, Jun 7, 2019 at 2:40 PM Carson Wentz<carson.wentz@gmail.com> wrote:

Here's the text content of the email. We'd like to extract it.

On Fri, Jun 6, 2019 at 2:53 AM Bob Smith<bob@gmail.com> wrote:
'hello'

## If you reply, text above this line is added to the request ##";
$withoutGmailHeader = "On Fri, Jun 7, 2019 at 2:40 PM Carson Wentz<carson.wentz@gmail.com>  wrote:

Here's the text content of the email. We'd like to extract it.

On Fri, Jun 6, 2019 at 2:53 AM Bob Smith<bob@gmail.com> wrote:
'hello'

## If you reply, text above this line is added to the request ##";

$pattern = "/^(?:On .+?> wrote:)?((\R|.)+?)## If you reply, text above this line is added to the request ##/";

preg_match($pattern, $withGmailHeader, $match);
echo "\n=> With Gmail header:\n";
var_export($match[1]);
echo "\n\n=> Without Gmail header: (note the extra space after >)\n";
preg_match($pattern, $withoutGmailHeader, $match);
var_export($match[1]);

输出:

=> With Gmail header:
'

Here\'s the text content of the email. We\'d like to extract it.

On Fri, Jun 6, 2019 at 2:53 AM Bob Smith<bob@gmail.com> wrote:
\'hello\'

'

=> Without Gmail header (note the extra space after >):
'On Fri, Jun 7, 2019 at 2:40 PM Carson Wentz<carson.wentz@gmail.com>  wrote:

Here\'s the text content of the email. We\'d like to extract it.

On Fri, Jun 6, 2019 at 2:53 AM Bob Smith<bob@gmail.com> wrote:
\'hello\'

'