preg_replace导致美元符号被删除

时间:2013-09-24 23:38:02

标签: php regex string cakephp preg-replace

我有一个电子邮件系统,用户在其中编写邮件并发送邮件。 我刚发现的主要问题,请考虑此代码

    $findEmail = $this->Data->field('body', array('id' => 1610));

    //$getUserEmailTemplate will take frm dbase and e.g: 
    //Hi, @@MESSAGE@@. From: StackOverflow
    //It should change @@MESSAGE@@ part to data from $findEmail (in this example is the $74.97 ...)

    $getUserEmailTemplate = $findUser['User']['email_template'];
    $emailMessage = preg_replace('/\B@@MESSAGE@@\B/u', $findEmail, $getUserEmailTemplate);

    debug($findEmail);
    debug($emailMessage);

并考虑此输入以获取$ findemail结果的电子邮件:

$74.97
$735.00s

$ email消息将导致:

.97
5.00s

我该如何解决这个问题?我觉得我的preg_replace模式存在问题。

用户模板可以是任何内容,只要有@@ MESSAGE @@,该部分将被更改为用户消息输入。

谢谢

5 个答案:

答案 0 :(得分:12)

预先解析替换文本,以便在后跟数字时转义$(请记住,$n在替换文本中使用时具有特殊含义)。请参阅php.net文档页面上的comment

  

如果您的替换文本有可能包含任何字符串,例如   “0.95美元”,你需要逃避那些$ n反向引用:

<?php
  function escape_backreference($x){
    return preg_replace('/\$(\d)/', '\\\$$1', $x);
  }
?>

答案 1 :(得分:1)

投票功能高的函数escape_backreference在一般情况下是不完整的:它只会转义格式为$n的反向引用,而不会转义为${n}或{{1} }。

要转义任何潜在的反向引用,请更改

\n

    $emailMessage = preg_replace('/\B@@MESSAGE@@\B/u', $findEmail, $getUserEmailTemplate);

答案 2 :(得分:0)

如果(曾经)某个模板已经在$getUserEmailTemplate中,那么你确实用这一行覆盖(销毁)了它;

$getUserEmailTemplate = "@@MESSAGE@@";

因此,只需删除此行并确保$getUserEmailTemplate确实包含任何内容,最重要的是模板。

答案 3 :(得分:0)

原因如下:

替换文字的abc 123部分代表找到的第一组/匹配。因此,如果您有preg_match('/([\w]+)-([\d]+)/')并尝试$1 = abc,则正则表达式会在内部存储$2 = 123$text = '[shortcode]'; $replacement = ' some $var $101 text'; $result = preg_replace('/\[shortcode\]/', $var, $text); // returns "some $var 1 text" 。这些变量即使没有价值也会存在。

所以,例如:

$10

由于匹配组$NN为空,因此将替换为空字符串。

这就是为什么在运行preg_replace函数之前需要从REPLACEMENT文本中查看任何window.localStorage的原因。

快乐的编码。

答案 4 :(得分:-1)

猜猜你的模板只包含“纯”PHP并尝试使用$ 74作为变量,它不存在且不包含任何数据。因此,请将模板中的引号更改为单引号'

猜测模板:

$tpl = "Sum: $74.97"; //results in "Sum: .97"

更正的模板:

$tpl = 'Sum: $74.97'; //results in "Sum: $74.97"