检查并替换字符在线路的末端或空格之前



我当前有两个阵列,我正在尝试检查一个单词中的最后两个字母,并在第一个数组匹配的情况下将其替换为其他字符。我目前正在努力执行此操作,直到行结束,但是我无法弄清楚如何为不在行末尾的单词做到这一点。

以下是我的阵列外观的一个示例。这些是从数据库查询中填充的。字符可以是任何Unicode字符,因此不一定在A-Z或A-Z范围内。

$array1 = ['mp', 'tm', 'de', 'HK'];
$array2 = ['MAP', 'TM', "DECIMAL", '字'];

我当前的代码看起来像这样:

$mystring = "samplemp";
$last = substr($mystring, -2);
$newlast = str_replace($array1, $array2, $last);
if ($last != $newlast){
    $mystring = substr($mystr, 0, 2).$newlast;
}

我工作的内容:

因此,我当前的代码查看了字符串中的最后两个字符。例如,如果最后两个字符是" MP",则用" MAP"代替它们。因此,如果我的字符串看起来像:

samplemp

它正确更改为

sampleMAP

到目前为止,一切正常。

问题

我遇到的问题是处理并非在字符串结尾处的单词。例如:

samplemp okay de     hellotm
blatm theHK end

应替换为

sampleMAP okay DECIMAL     helloTM
blaTM the字 end

我希望能够考虑所有空白空间,包括空格,标签和马车返回。但是,空格必须保持完整且不会更改。空间必须作为空间,标签作为标签和托架返回作为返回。

到目前为止,我已经能够弄清楚我可能需要使用s逃生字符使用正则表达式来说明空格。但是,我无法理解如何将其用于在数组上作用的str_replace函数。有没有办法做到这一点?如果没有,我该怎么办才能使它工作?

我会做:

$string = <<<EOD
samplemp okay de     hellotm
blatm theHK end
EOD;
$array1 = ['mp', 'tm', 'de', 'HK'];
$array2 = ['MAP', 'TM', "DECIMAL", '字'];
$hash = array_combine($array1, $array2);
foreach($hash as $k => $v) {
    $string = preg_replace_callback('/'.preg_quote($k).'(?=s|$)/u', function($m) use($v) {
        return $v;
    },
    $string
    );
}
echo $string,"n";

(?=s|$)是一个lookahead,确保我们有任何空间(即空间,制表,马车返回,线折,...(或搜索键后字符串的末端。因此,我们保持空白不变。

/u是Unicode标志。

输出:

sampleMAP okay DECIMAL     helloTM
blaTM the字 end

使用带有lookahead的正则表达式,该表达式与字符串末端的任何whitespace匹配。

$array1 = ['/mp(?=s*$)/', 'tm(?=s*$)/', 'de(?=s*$)/'];
$array2 = ['MAP', 'TM', "DECIMAL"];
$newlast = preg_replace($array1, $array2, $last);

而无需测试,您可以做这样的事情

$array2 = ['mp' => 'MAP', 'tm' => 'TM', 'de' => "DECIMAL"];
$mystring = "samplemp";
$patt = '/('.implode( '|',array_keys($array2) ) .')b/';
$newlast = preg_replace_callback($patt , function( $m ) use ($array2){
    return $array2[$m[1]];
}, $mystring);
echo "n$newlast";

使用preg_replace_callback,您可以避免通过一系列输入进行循环,而是循环循环匹配,这应该可以提供一些较小的性能,看到在大多数情况下,将有更多的可能性(输入(。>

此类的正则表达式是:

/(mp|tm|de)b/

因此,这将捕获 mptmde,但仅在字符串的末尾或单词末尾的末尾使用一个单词break b,因此它不会与 dende匹配。p>回调零件是相当大的海峡,每次进行输入字符串中的匹配时,都会触发回调,并且该匹配将其作为第一个参数传递到该函数中。比赛的格式就像preg_match的作品一样。然后,无论您返回什么都用作替换字符串。这只是键=>值对中的一种简单访问方式。

闭合中的

use只是一个范围分辨率运算符,它使您可以传递通常在闭合范围之外的变量。'

这样做的真正优势是,您不必为图案使用循环准备数组,而只需爆炸即可。另外,它在匹配项上循环,而不是输入。其他大多数答案都循环准备模式,然后在图案上进行另一个循环。"在比赛上循环是不可避免的",我说循环宽松地意味着重复的操作。

在任何情况下,您都可以在此处测试REGX

https://regex101.com/r/ayw111/1

您可以使用正则表达式进行。

首先将您的模式转换为正则表达式,然后将' b'附加到您的模式,这意味着单词边界(空间,tab,eol ...(:

foreach($array1 as $k => $v) {
  $array1[$k] = '/'.$v.'\b/';
}

然后替换为preg_replace:

$result = preg_replace($array1, $array2, "samplemp okay hellotm");

这是我敲在一起的快速功能,应该做您需要的事情。它将字符串拆分,然后在Array1中查找最后2个字母。如果找到它,它将用array2中的末端字母替换。如果它到达循环的末端并且尚未返回,则将返回原始字符串。

<?php
function replaceString($string)
{
    $array1 = ['mp', 'tm', 'de'];
    $array2 = ['MAP', 'TM', "DECIMAL"];
    $first = substr($string, 0, -2);
    $last = substr($string, -2);
    $split = [
      'start' => $first,
      'end' => $last,  
    ];
    foreach ($array1 as $key => $val) {
        if ($val == $split['end']) {
            $word = $split['start'].$array2[$key];
            return $word;
        }
    }
    return $string;
}

echo replaceString("samplemp")."n";
echo replaceString("okay")."n";
echo replaceString("hellotm")."n";

samplemap好的hellotm

LIVE示例此处https://3v4l.org/fjciy

您可以将字符串分为数组,然后检查替换的特定单词。尝试以下操作:

$array1 = ['mp', 'tm', 'de', 'HK'];
$array2 = ['MAP', 'TM', "DECIMAL", '字'];
$mystring = "samplemp t okay hellotm";
preg_match_all('/s+/', $mystring,$space_array);
$space_array = isset($space_array[0])?$space_array[0]:$space_array;
$test_array = preg_split('/s+/', $mystring);
$change_array= array();
$new_str = "";
foreach ($test_array as $key => $value) {         
    $last = substr($value, -2);
    $newlast = str_replace($array1, $array2, $last);
    if ($last != $newlast){
        $value = substr($value, 0, strlen($value)-2).$newlast;
    }
    $value .= isset($space_array[$key])?$space_array[$key]:"";
    $change_array[] = $value;    
}
var_dump(implode("", $change_array));

进行比其他一些答案更简单:

$mystring = <<<EOD
samplemp okay MADE  de     hellotm
blatm theHK end
EOD;
$array1 = ['mp', 'tm', 'de', 'HK'];
$array2 = ['MAP', 'TM', "DECIMAL", '字'];
foreach($array1 as $key=>$v){
    $mystring = preg_replace("/".preg_quote($v)."b/u", $array2[$key], $mystring);
}

最新更新