1

我允许在我的软件中发送的电子邮件中使用自定义字段。我使用 CKEditor,所以他们可以编写和格式化他们的电子邮件。带有自定义字段的 HTML 格式电子邮件的示例是:

<p>嗨,%firstname%,</p>

<p>呜呜呜……</p>

我使用以下代码来检测和替换这些字段。

preg_match_all('`\%(?![0-9])([a-zA-Z0-9_-]+)\%`', $message, $contact_fields);
if (!empty($contact_fields[1])) {
    foreach($contact_fields[1] AS $contact_field) {
        $replace_width = 'do the magic here';
        $message = str_replace('%' . $contact_field . '%', $replace_with, $message);
    }
}

问题有时是 CKEditor 这样做:

<p>嗨 %<span>名字</span>%,</p>

<p>呜呜呜……</p>

所以它最终不会替换字段。我的用户想知道为什么这是因为他们看不到 HTML 代码。

关于如何使这个正则表达式工作的任何建议,以便如果或任何其他 HTML 属性最终出现在我的自定义字段中,它仍然会替换它?

谢谢

4

3 回答 3

2

我认为错误是“Az”而不是“AZ”。尝试这个:

preg_match_all('`\%(?![0-9])([a-zA-Z0-9_-]+)\%`', $message, $contact_fields);
于 2013-11-05T17:13:51.323 回答
2

干得好:

\%(?![0-9])(?:<[^<]+?>)?([a-zA-Z0-9_-]+)(?:[\s]?<[^<]+?>)?\%

(?:<[^<]+?>)?在您的捕获组之前和之后添加。
(?:...)在不创建捕获组的情况下对字符进行分组,<[^<]+?>匹配 html-tags,最后一个?使其可选。因此,当 html-tags 存在和不存在时,这将匹配。
在第二个非捕获组中,我在匹配 html 标记之前插入,如在您的示例中, and[\s]?之间有一个空格。firstname</span>

示例可以在这里找到:http ://regexr.com?372fe

如果您想在捕获组中包含 html-tags,只需移动括号以创建一个大型捕获组匹配<tag>string</tag>

\%(?![0-9])((?:<[^<]+?>)?[a-zA-Z0-9_-]+(?:[\s]?<[^<]+?>)?)\%
于 2013-11-05T16:53:56.290 回答
0

问题是,您如何添加逻辑来确定其中哪些不需要的文本%...%是可以安全删除的 HTML 标记,而不是自定义字段名称的一部分。我的建议是简单地找到所有%...%存在的情况,strip_tags()在内容上运行,然后查看它是否是字段匹配。使用preg_replace_callback()可能适用于此:

$pattern = '/\%(?![0-9])([a-zA-z0-9_-]+)\%/U'; // note use of ungreedy match

$cleaned_string = preg_replace_callback($pattern, function($matches) {
   $field_name = strip_tags($matches[1]);
   // I assume you have custom fields and values in an associative array with field name as key.
   // You can change this part to match your actual case
   if(array_key_exists($field_name, $array_of_custom_fields)) {
       return $array_of_custom_fields[$field_name];
   } else {
       return ''; // empty string since field doesn't match
   }
}, $message); 
于 2013-11-05T17:04:57.843 回答