我允许在我的软件中发送的电子邮件中的自定义字段。我使用CKEditor,因此他们可以编写和格式化他们的电子邮件。具有自定义字段的HTML格式电子邮件的示例是:
< p> Hi%firstname%,< / p>
< p> Blah blah blah .....< / 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> Hi%< span> firstname< / span>%,< / p>
< p> Blah blah blah .....< / p>
所以它最终不会替换字段。我的用户想知道为什么这是因为他们看不到HTML代码。
关于我如何使这个正则表达式工作的任何建议如此完整或任何其他HTML属性最终在我的自定义字段中,它仍将替换它?
由于
本
答案 0 :(得分:2)
你走了:
\%(?![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]?<[^<]+?>)?)\%
答案 1 :(得分:2)
我认为错误是“A-z”而不是“A-Z”。试试这个:
preg_match_all('`\%(?![0-9])([a-zA-Z0-9_-]+)\%`', $message, $contact_fields);
答案 2 :(得分: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);