我允许在我的软件中发送的电子邮件中自定义字段。我使用CKEditor,所以他们可以编写和格式化他们的电子邮件。带有自定义字段的 HTML 格式电子邮件的示例如下:
Hi %firstname%,
等等等等.....
我使用以下代码来检测和替换这些字段。
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会这样做:
Hi %firstname%,
等等等等.....
因此,它最终不会替换字段。我的用户想知道为什么这是因为他们看不到 HTML 代码。
关于如何使此正则表达式工作的任何建议,以便如果或任何其他 HTML 属性最终出现在我的自定义字段中,它仍然会替换它?
谢谢
本
你去吧:
'%(?![0-9])(?:<[^<]+?>)?([a-zA-Z0-9_-]+)(?:['s]?<[^<]+?>)?'%
我在您的捕获组之前和之后添加了(?:<[^<]+?>)?
。
(?:...)
字符分组而不创建捕获组,<[^<]+?>
匹配 html 标记,最后一个?
使其成为可选。因此,当 html 标记存在和不存在时,这将匹配。
在第二个非捕获组中,我在匹配 html 标签之前插入了 ['s]?
,就像在您的示例中一样,firstname
和 </span>
之间只有一个空格。
示例可以在这里找到:http://regexr.com?372fe
如果要在捕获组中包含html标记,只需移动括号即可创建与<tag>string</tag>
匹配的大型捕获组:
'%(?![0-9])((?:<[^<]+?>)?[a-zA-Z0-9_-]+(?:['s]?<[^<]+?>)?)'%
我认为错误是"A-z"而不是"A-Z"。试试这个:
preg_match_all('`'%(?![0-9])([a-zA-Z0-9_-]+)'%`', $message, $contact_fields);
问题是,您如何添加逻辑来确定%...%
中哪些不需要的文本是可以安全删除的 HTML 标记,而不是自定义字段名称的 HTML 标记.part。 我的建议是简单地找到存在%...%
的所有情况,对内容运行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);