【问题标题】:PHP: Extract digits and replacing all occurrences from a string with functionsPHP:提取数字并用函数替换字符串中的所有出现
【发布时间】:2018-01-28 20:36:31
【问题描述】:

我有这个字符串:

$string = '[userid=77] has created a new task.
[userid=59] and [userid=66] is are subscribed.
This task is assigned to [accountid=2248]';

我想全部替换 [userid=DIGIT]displayuser(DIGIT) 和所有[accountid=DIGIT]displayaccount(DIGIT)

所以字符串应该是这样结束的:

$string = displayuser(77).' has created a new task.
    '.displayuser(59).' and '.displayuser(66).' is are subscribed.
    This task is assigned to '.displayaccount(2248).';

到目前为止我尝试过的只显示 first [userid=DIGIT]

$text = "[userid=77] has created a new task. [userid=59] and [userid=66] is are subscribed. This task is assigned to [accountid=28]";
print "Before: ".$text."<br/><br/>";

$matches = array();

// Get [userid=DIGIT]
$found = preg_match('@\[userid[^\]]+\]@', $text, $matches);
print $matches[0]."<br/><br/>";

// Get DIGIT withing [userid=DIGIT]
$found2 = preg_match('!\d+!', $matches[0], $match_id);
echo $match_id[0]."<br/><br/>";

// Replace [userid=DIGIT] with function(DIGIT)
$new = str_replace($matches[0],displayuser($match_id[0]),$text);

【问题讨论】:

  • 看来您想使用preg_replace_callback 匹配正则表达式 ($pattern) ~\[([a-z]+)=(\d+)\]~ 并用适当的函数调用替换文本。
  • 请展示你的尝试。
  • @h2ooooooo 但是 preg_replace_callback 只会获得第一次出现或用户 ID 或其他。没有?
  • 绝对不是。它会为每场比赛调用回调。如果它只匹配一个匹配,为什么它会有一个限制变量?
  • @h2ooooooo 请查看我的编辑,因为我尝试匹配(每个?) [userid=DIGIT],获取数字并将其替换为它的功能。似乎有效,但仅适用于第一次出现而不是每次出现。抱歉,我对 PHP 还很陌生。

标签: php regex string preg-replace replaceall


【解决方案1】:

您可以使用正则表达式匹配并捕获useridaccountid 之后的数字,以及将捕获的值映射到作为第二个参数传递的匿名回调函数内的必要字符串的preg_replace_callback function

$text = preg_replace_callback('@\[userid=(\d+)]|\[accountid=(\d+)]@', function($m) {
    return !empty($m[1]) ? displayuser($m[1]) : displayaccount($m[2]);
}, $text);

请参阅PHP demo

\[userid=(\d+)]|\[accountid=(\d+)] 模式将匹配 [userid=&lt;DIGITS_HERE&gt;] 将数字放入组 1 或 [accountid=&lt;DIGITS_HERE&gt;] 将这些数字放入组 2。在回调中使用 !empty($m[1]),我们检查组 1 是否匹配,如果是,使用displayuser($m[1])通过用户ID获取用户名,否则我们使用displayaccount($m[2])通过账户ID获取账户名。

【讨论】:

    【解决方案2】:

    按照@h2ooooooo 的建议使用 preg_replace_callback 我想出了以下完美的方法

    $text = "[userid=77] has created a new task. [userid=59] and [userid=66] is are subscribed. This task is assigned to [accountid=4]";
    
    function displaycontact_cb($matches){
      $found2 = preg_match('!\d+!', $matches[0], $match_id);
      return displayuser($match_id[0]);
    }
    
    function displayaccount_cb($matches){
      $found2 = preg_match('!\d+!', $matches[0], $match_id);
      return displaycontact($match_id[0],"account");
    }
    
    $text = preg_replace_callback('@\[userid[^\]]+\]@',"displaycontact_cb",$text);
    $text = preg_replace_callback('@\[accountid[^\]]+\]@',"displayaccount_cb",$text);
    
    print $text;
    

    【讨论】:

      猜你喜欢
      • 2012-08-01
      • 2013-12-06
      • 2021-12-27
      • 2022-11-21
      • 2016-02-03
      • 2023-03-09
      • 2015-05-30
      • 1970-01-01
      • 2013-04-15
      相关资源
      最近更新 更多