PHP preg_replace多个替换

slwdgvem  于 2022-12-02  发布在  PHP
关注(0)|答案(4)|浏览(237)

我对正则表达式比较弱,这让我很头疼。我只是试着从字符串中提取时间,并修改时间的文本。我得到的字符串有以下形式:

"Some text I don't care about | 2.3 seconds ago"
"Some text I don't care about | 5.2 minutes ago"
"Some text I don't care about | 7.0 hours ago"
"Some text I don't care about | 1.9 days ago"

我想把上面的字符串分别替换为它们的形式:

"2.3 secs"
"5.2 mins"
"7.0 hrs"
"1.9 days"

我知道在regex中替换的基本知识,但是要删除我想要的文本前面和后面的多个东西,同时用“hrs”替换“hours”等超出了我的regex技能水平。
任何帮助都将不胜感激。

  • 谢谢-谢谢

编辑:

经过一番折腾,我找到了一个使用多个不同函数的解决方案。我并不完全喜欢它,但它很有效。如果可能的话,我更喜欢单个preg_replace解决方案。下面是我目前的 * 丑陋 * 解决方案:

$testString = "This is text I don't care about | 7.3 seconds ago";
$testString = array_shift(array_reverse(explode('|', $testString)));
$pattern = array('/seconds/', '/minutes/', '/hours/', '/ago/');
$replace = array('secs', 'mins', 'hrs', '');
$testString = trim(preg_replace($pattern, $replace, $testString));

输出为:7.3 secs

ijnw1ujt

ijnw1ujt1#

如果您真的希望搜索/替换在一行中进行,可以执行以下操作:

$time_map = array(
  'seconds' => 'secs',
  'minutes' => 'mins',
  'hours'   => 'hrs',
  'days'    => 'days',
);

$data = array(
    "Some text I don't care about | 2.3 seconds ago",
    "Some text I don't care about | 5.2 minutes ago",
    "Some text I don't care about | 7.0 hours ago",
    "Some text I don't care about | 1.9 days ago",
);

foreach ($data as $line) {
    $time_data = preg_replace_callback("/(.*|\s*)([0-9]+\.[0-9]+) (\w+) ago/",  function ($matches) use ($time_map) {return $matches[2] . " " . $time_map[$matches[3]];}, $line);
    print "$time_data\n";
}

其产生:

2.3 secs
5.2 mins
7.0 hrs
1.9 days
x8diyxa7

x8diyxa72#

preg_replace有一个可选的第四个参数,它是一个限制。该限制是它可以替换的最大匹配数。Php preg_replace是自动全局的,这意味着它将替换所有匹配,除非你为该限制输入一个正数。
http://php.net/manual/en/function.preg-replace.php

46qrfjad

46qrfjad3#

使用preg_matchstr_replace函数的简单解决方案:

$testString = "This is text I don't care about | 7.3 seconds ago";
$timeUnitsmap = ["secs" => "seconds", "mins" => "minutes", "hrs" => "hours"];

preg_match("/\b[0-9.]+? \w+?\b/i", $testString, $matches);
$testString = str_replace(array_values($timeUnitsmap), array_keys($timeUnitsmap), $matches[0]);

print_r($testString);  // "7.3 secs"

或者使用preg_replace_callbackarray_search函数:

...
$testString = preg_replace_callback(["/.*?\b([0-9.]+? )(\w+?)\b.*/"], function($m) use($timeUnitsmap){
    return $m[1]. array_search($m[2], $timeUnitsmap);
}, $testString);
vktxenjb

vktxenjb4#

这显然不再是必需的,只是为了表明,如果你通过交替替换掉所有你不想要的部分,这样的事情可以用一个表达式来完成。
例如,将^.+\| +|(?:ond|ute|ou)| ago替换为空字符串:

$result = preg_replace('/^.+\| +|(?:ond|ute|ou)| ago/', '', $yourData);

请参阅regex demo

相关问题