Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Examine and replace characters at end of line or before whitespace

I currently have two arrays set up, and I am trying to examine the last two letters in a word and replace it with other characters if there is a match with the first array. I currently have it working to do this to the end of the line, but I cannot figure out how to do this for words that are not at the end of a line.

The following is an example of what my arrays might look like. These are populated from a database query. The characters could be any Unicode character, so not necessarily in the range from A-Z or a-z.

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

My current code looks like this:

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

What I have working:

So, the code I currently have looks at the last two characters in the string. If the last two characters are "mp" for example it replaces them with "MAP". So if my string looks like:

samplemp

it gets changed correctly to

sampleMAP

up to this point everything is working correctly.

The problem

The issue I am having is dealing with the words that are not at the end of a string. For example:

samplemp okay de     hellotm
blatm theHK end

should be replaced with

sampleMAP okay DECIMAL     helloTM
blaTM the字 end

I want to be able to account for all white space including spaces, tabs, and carriage returns. However, the whitespace must remain intact and not changed. Spaces must stay as spaces, tabs as tabs, and carriage returns as carriage returns.

So far, I've been able to figure out that I likely need to use a regular expression using the \s escape character to account for whitespace. However, I cannot comprehend how to use this with the str_replace functions which are acting on the arrays. Is there a way to do this? If not, what else should I do to get this to work?

like image 458
kojow7 Avatar asked Jun 23 '17 23:06

kojow7


2 Answers

I'd do:

$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";

Where (?=\s|$) is a lookahead that makes sure we have any kind of space (ie. space, tabulation, carriage return, linebreak, ...) or the end of the string after the searched key. With this, we keep the white space unchanged.

/u is unicode flag.

Output:

sampleMAP okay DECIMAL     helloTM
blaTM the字 end
like image 124
Toto Avatar answered Nov 15 '22 18:11

Toto


Use a regular expression with a lookahead that matches any sequence of whitespace at the end of the string.

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

$newlast = preg_replace($array1, $array2, $last);
like image 2
Barmar Avatar answered Nov 15 '22 18:11

Barmar