替换单词并保持找到的字符串区分大小写

问题描述 投票:0回答:3

我正在创建一个 php 应用程序来格式化文件。因此,我需要在维护案例的同时应用查找替换过程。

例如,我需要将“员工”替换为“车辆”。

$file_content = "Employees are employees_category MyEmployees kitEMPLOYEESMATCH";
$f = 'employees';
$r = 'vehicles';

echo str_ireplace($f, $r, $file_content);
   

电流输出:

vehicles are vehicles_category Myvehicles kitvehiclesMATCH

所需输出:

Vehicles are vehicles_category MyVehicles kitVEHICLESMATCH
php regex replace case-sensitive
3个回答
1
投票

您可以通过分别替换每种情况来使用类似的内容:

<?php
     $file_content = "Employees are employees_category MyEmployees kitEMPLOYEESMATCH";
     $f = 'employees';
     $r = 'vehicles';

     $res = str_replace($f, $r, $file_content); // replace for lower case
     $res = str_replace(strtoupper($f), strtoupper($r), $res); // replace for upper case
     $res = str_replace(ucwords($f), ucwords($r), $res); // replace for proper case (capital in first letter of word)
     echo $res
   
?>

0
投票

虽然 SJ11 的答案因其简洁性而有吸引力,但它很容易对已替换的子字符串进行意外替换——尽管使用 OP 的示例数据是不可能的。

为了确保替换内容不被替换,您必须仅对输入字符串进行一次传递。

为了实用,我将包含

preg_quote()
,这样当
$r
值包含正则表达式中具有特殊含义的字符时,模式不会中断。

代码:(演示)(PHP7.4演示

$file_content = "Employees are employees_category MyEmployees kitEMPLOYEESMATCH";
$f = 'employees';
$r = 'vehicles';

$pattern = '~('
           . implode(
               ')|(',
               [
                   preg_quote($f, '~'),
                   preg_quote(ucfirst($f), '~'),
                   preg_quote(strtoupper($f), '~')
               ]
           ) . ')~';
$lookup = [
    1 => $r,
    2 => ucfirst($r),
    3 => strtoupper($r)
];

var_export(
    preg_replace_callback(
        $pattern,
        function($m) use ($lookup) {
            return $lookup[count($m) - 1];
        },
        $file_content
    )
);

输出:(单引号来自

var_export()

'Vehicles are vehicles_category MyVehicles kitVEHICLESMATCH'

0
投票

谢谢@mickmackusa - 很好的解决方案,但我需要一个版本来选择仅替换整个单词,例如,当用英国拼写“mum”替换美国拼写“mom”时,它不会同时用 mument 替换“moment” .

我还添加了一个快速

str_contains()
检查,因为我正在使用此函数来替换很多单词,并且如果该单词首先根本不存在,我想减少正则表达式时间。

这是我根据您的代码构建的函数来执行此操作:

function replaceWithCase($source, $replacement, $string, $whole_word_only = false) {

    if(!str_contains(strtolower($string), strtolower($source))) return $string;

    $word_boundary = '';

    if($whole_word_only) {
        $word_boundary = '/\b';
    }

    $pattern = '~' . $word_boundary . '('
                . implode(
                    ')|(',
                    [
                        preg_quote($source, '~'),
                        preg_quote(ucfirst($source), '~'),
                        preg_quote(strtoupper($source), '~')
                    ]
                ) . ')' . $word_boundary . '~';

    $lookup = [
        1 => $replacement,
        2 => ucfirst($replacement),
        3 => strtoupper($replacement)
    ];

    $result =
        preg_replace_callback(
            $pattern,
            function($m) use ($lookup) {
                return $lookup[count($m) - 1];
            },
            $string
        );

    return $result;
}
© www.soinside.com 2019 - 2024. All rights reserved.