检查并替换行尾或空格前的字符

时间:2017-06-23 23:13:35

标签: php arrays string replace whitespace

我目前设置了两个数组,我正在尝试检查单词中的最后两个字母,如果与第一个数组匹配则将其替换为其他字符。我目前正在努力做到这一点到最后一行,但我无法弄清楚如何对不在一行末尾的单词这样做。

以下是我的数组可能的样子。这些是从数据库查询填充的。字符可以是任何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函数中使用它。有没有办法做到这一点?如果没有,我还应该做些什么才能让它发挥作用?

7 个答案:

答案 0 :(得分:4)

我会这样做:

 target.setOnTouchListener(new View.OnTouchListener() {

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            Matrix inverse = new Matrix();
            imageView.getImageMatrix().invert(inverse);
            float[] touchPoint = new float[]{event.getX(), event.getY()};
            inverse.mapPoints(touchPoint);
            int x = (int) touchPoint[0];
            int y = (int) touchPoint[1];

            ConstraintSet set = new ConstraintSet();
            ImageView view = new ImageView(this);
            ConstraintLayout.LayoutParams vp =
                new ConstraintLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
                        ViewGroup.LayoutParams.WRAP_CONTENT);
            Bitmap bm = BitmapFactory.decodeResource(getResources(),
                R.drawable.bullet);
            view.setImageBitmap(bm);
            layout.addView(view, 7, vp);
            set.clone(layout);
            set.connect(view.getId(), ConstraintSet.TOP,
            target.getId(), ConstraintSet.TOP, (int) y - 60);
            set.connect(view.getId(), ConstraintSet.LEFT, target.getId(), ConstraintSet.LEFT, (int) x);
            set.applyTo(layout);

        }
    });

其中$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|$)是unicode标志。

<强>输出:

/u

答案 1 :(得分:2)

使用带有前瞻的正则表达式,该前瞻符合字符串末尾的任何空格序列。

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

$newlast = preg_replace($array1, $array2, $last);

答案 2 :(得分:2)

如果没有测试,你可以做这样的事情

$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,但最后只能使用分词\b,如字符串末尾或结尾例如,单词dende不匹配。

回调部分非常紧凑,每次输入字符串中的匹配都会触发回调,并且该匹配作为第一个参数传递给该函数。匹配的格式就像preg_match一样。然后,无论您返回什么,都将用作替换字符串。这只是一种简单的访问方式:key =&gt;数组中的值对。

闭包中的

use只是一个范围解析运算符,它允许您传入通常在闭包范围之外的变量。 &#39;

这样做的真正好处是,您不必使用循环为您的模式准备阵列,只需对其进行内爆即可。此外,它在匹配上循环,而不是在输入上循环。大多数其他答案都会循环准备模式,然后是模式上的另一个循环。 &#34;在比赛中循环是不可避免的&#34;我说松散只是意味着重复操作。

无论如何,你可以在这里测试Regx

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

答案 3 :(得分:1)

你可以使用正则表达式来做到这一点。

首先将您的模式转换为正则表达式并附加&#39; \ b&#39;你的模式意味着单词边界(空格,制表符,EOL ...):

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

然后用preg_replace替换:

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

答案 4 :(得分:1)

您可以将字符串拆分为数组,然后检查特定字词以供替换。试试这个:

var1

答案 5 :(得分:1)

这是一个快速的功能,我拼凑了应该做你需要的。它拆分字符串,然后查找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

现场示例https://3v4l.org/fJCIY

答案 6 :(得分:1)

比这里已有的其他一些答案简单一些:

$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);
}