The Web Design Group

... Making the Web accessible to all.

Welcome Guest ( Log In | Register )

 
Reply to this topicStart new topic
> Exact Match, How to find exact (whole only) match
Dag
post Apr 8 2020, 06:27 AM
Post #1


Advanced Member
****

Group: Members
Posts: 102
Joined: 24-October 06
Member No.: 549



I need to find and replace strings inside the text. In this case, text is in the array format. I don't want to replace parts of the string if full string do not match. Samples:
CODE

$find = array('Dominican Republic','Netherlands Antilles','Netherlands','Republic');
$replace = array('Доминиканская Республика','Нидерландские Антильские острова','Нидерланды','Република');
$text = array('Netherlands','Caribbean Netherlands','Republic','Dominican Republic','Netherlands Antilles','My Personal Republic');
$textNew = str_replace($find,$replace,$text);

Result is
CODE

Array
(
    [0] => Нидерланды
    [1] => Caribbean Нидерланды
    [2] => Република
    [3] => Доминиканская Республика
    [4] => Нидерландские Антильские острова
    [5] => My Personal Република
)

Walking through string by string... here is one string only:
CODE

$text = array('Caribbean Netherlands');

Result is
CODE

Array
(
    [0] => Caribbean Нидерланды
)

Regexp "/b" didn't help.
Any ides about this? Is it well known issue and is it very simple to be solved?
Thanks in advance.
User is offlinePM
Go to the top of the page
Toggle Multi-post QuotingQuote Post
Christian J
post Apr 8 2020, 04:38 PM
Post #2


.
********

Group: WDG Moderators
Posts: 8,444
Joined: 10-August 06
Member No.: 7



QUOTE(Dag @ Apr 8 2020, 01:27 PM) *

I don't want to replace parts of the string if full string do not match.

I suppose that's what str_replace() is meant to do. Usually $text is a string, but even if it's an array the function just checks the string value of each $text array item.

QUOTE
Any ides about this? Is it well known issue and is it very simple to be solved?

I was thinking maybe you could do this:

CODE
$find = array('foo', 'bar');
$replace = array('FOO', 'BAR');
$text = array('foo', 'bar', 'foobar');

for($i=0; $i<count($text); $i++)
{
    for($j=0; $j<count($find); $j++)
    {
        if($text[$i]==$find[$j])
        {
            $textNew[$i]=$replace[$j];
        }
        else
        {
            $textNew[$i]=$text[$i];
        }
    }
}

echo '<pre>';
print_r($textNew);
echo '</pre>';

but for some reason it returns this:

CODE
Array
(
    [0] => foo
    [1] => BAR
    [2] => foobar
)

[1] and [2] are what I expected, but shouldn't [0] be uppercase FOO? Haven't done any PHP in a long time. unsure.gif

User is offlinePM
Go to the top of the page
Toggle Multi-post QuotingQuote Post
Dag
post Apr 9 2020, 05:00 AM
Post #3


Advanced Member
****

Group: Members
Posts: 102
Joined: 24-October 06
Member No.: 549



Hi Chris.

See, text is always string. I just take it from array, phrase by phrase (element by element). So, I have very short string 20-40 characters and replacing it (lat) with another (cyr). My lat string has no boundaries, I can't say "Take this line from here to here"... what I need is ellementary: take all this string and replace with this one. If you haven't cyr translation, keep it as is, don't mess it...

It must be solvable with some preg_replace(match) trick... I remember that I saw someshere attitute... as do it but in lazy mode... less aggressive...

Doing all of that with character-one-by-one would be very slow... too many lines... My sample is very clear I think...

When I find it, I'll post the solution here...
User is offlinePM
Go to the top of the page
Toggle Multi-post QuotingQuote Post
Christian J
post Apr 9 2020, 06:10 AM
Post #4


.
********

Group: WDG Moderators
Posts: 8,444
Joined: 10-August 06
Member No.: 7



QUOTE(Christian J @ Apr 8 2020, 11:38 PM) *

but for some reason it returns this:

CODE
Array
(
    [0] => foo
    [1] => BAR
    [2] => foobar
)

[1] and [2] are what I expected, but shouldn't [0] be uppercase FOO? Haven't done any PHP in a long time. unsure.gif

I think I found the bug in my script above. The very first $j iteration works correct:

CODE
if($text[0]==$find[0]) // foo==foo

and does change "foo" to "FOO" in $textNew[0]. But in the next $j iteration:

CODE
if($text[0]==$find[1]) // foo!=bar

the IF compares "foo" with "bar", and because that's FALSE, $textNew[0] is changed again (this time by the ELSE condition) from "FOO" to the "foo" value of $text[0]).

This version might work better:

CODE
$find = array('foo', 'bar');
$replace = array('FOO', 'BAR');
$text = array('foo', 'bar', 'foobar');

$textNew=$text; // I first copy the whole array, only changing values later (if needed)

for($i=0; $i<count($text); $i++)
{
    for($j=0; $j<count($find); $j++)
    {
        if($text[$i]==$find[$j])
        {
            $textNew[$i]=$replace[$j]; // change array values only when needed (no need for ELSE condition)
        }
    }
}

echo '<pre>';
print_r($textNew);
echo '</pre>';


User is offlinePM
Go to the top of the page
Toggle Multi-post QuotingQuote Post
Dag
post Apr 9 2020, 11:18 AM
Post #5


Advanced Member
****

Group: Members
Posts: 102
Joined: 24-October 06
Member No.: 549




Will you retry with my samples?

QUOTE(Christian J @ Apr 9 2020, 03:10 PM) *

QUOTE(Christian J @ Apr 8 2020, 11:38 PM) *

but for some reason it returns this:

CODE
Array
(
    [0] => foo
    [1] => BAR
    [2] => foobar
)

[1] and [2] are what I expected, but shouldn't [0] be uppercase FOO? Haven't done any PHP in a long time. unsure.gif

I think I found the bug in my script above. The very first $j iteration works correct:

CODE
if($text[0]==$find[0]) // foo==foo

and does change "foo" to "FOO" in $textNew[0]. But in the next $j iteration:

CODE
if($text[0]==$find[1]) // foo!=bar

the IF compares "foo" with "bar", and because that's FALSE, $textNew[0] is changed again (this time by the ELSE condition) from "FOO" to the "foo" value of $text[0]).

This version might work better:

CODE
$find = array('foo', 'bar');
$replace = array('FOO', 'BAR');
$text = array('foo', 'bar', 'foobar');

$textNew=$text; // I first copy the whole array, only changing values later (if needed)

for($i=0; $i<count($text); $i++)
{
    for($j=0; $j<count($find); $j++)
    {
        if($text[$i]==$find[$j])
        {
            $textNew[$i]=$replace[$j]; // change array values only when needed (no need for ELSE condition)
        }
    }
}

echo '<pre>';
print_r($textNew);
echo '</pre>';


User is offlinePM
Go to the top of the page
Toggle Multi-post QuotingQuote Post
Christian J
post Apr 9 2020, 01:31 PM
Post #6


.
********

Group: WDG Moderators
Posts: 8,444
Joined: 10-August 06
Member No.: 7



QUOTE(Dag @ Apr 9 2020, 06:18 PM) *

Will you retry with my samples?

Then I get:

CODE
Array
(
    [0] => Нидерланды
    [1] => Caribbean Netherlands
    [2] => Република
    [3] => Доминиканская Республика
    [4] => Нидерландские Антильские острова
    [5] => My Personal Republic
)

Is that what you want?
User is offlinePM
Go to the top of the page
Toggle Multi-post QuotingQuote Post
Dag
post Apr 9 2020, 08:35 PM
Post #7


Advanced Member
****

Group: Members
Posts: 102
Joined: 24-October 06
Member No.: 549



QUOTE(Christian J @ Apr 9 2020, 10:31 PM) *

CODE
Array
(
    [0] => Нидерланды
    [1] => Caribbean Netherlands
    [2] => Република
    [3] => Доминиканская Республика
    [4] => Нидерландские Антильские острова
    [5] => My Personal Republic
)

Is that what you want?


Well, at first sight seems ok. I need to check code on my real case. To many passes I think... need about day to back here with results.

So far, do check real-life use. if size doesn't matter, speed does.
https://www.laban.rs/c/
https://www.laban.rs/c/eng/
https://www.laban.rs/c/rus/
https://www.laban.rs/c/srp/
https://www.laban.rs/c/eng/rt_data
https://www.laban.rs/c/rus/rt_data
https://www.laban.rs/c/srp/rt_data

Pages with full tables have sorting available...
User is offlinePM
Go to the top of the page
Toggle Multi-post QuotingQuote Post
Dag
post Apr 12 2020, 01:01 PM
Post #8


Advanced Member
****

Group: Members
Posts: 102
Joined: 24-October 06
Member No.: 549



OK.
We don't need anything of that except one single line to compare execution.
My code is:
CODE

$text = str_replace($lgEng,$lgSec,$val[0]);

Your code is
CODE

if($text[$i]==$find[$j]) {
$text[$i]=$replace[$j];}

As text is always dirty enough with lot of slang, I need 2 passes with 2 differenet arrays: the second one is created manually and included in itself all unreplaced values (that array is not so big usually...). So, check by yourself both full codes. $lgEng is original source values and $corEng is array of values that have to be changed after first pass (remains unchanged)
What I am using:
CODE

foreach($abody as $val) {
    $tmp = str_replace($lgEng,$lgSec,$val[0]);    //- Only val[0] is to be changed (country name)
    $body = '<td>'.str_replace($corEng,$corSec,$tmp).'</td>';
    for($i = 1; $i < sizeof($val); $i++){    //- All of these are numbers
        $body .= '<td>'.$val[$i].'</td>';}
    $tbody .= "\t<tr>".$body."</tr>\n";
    $body = '';
}

Your code should looks like next:
CODE

foreach($abody as $val){
    $find = $lgEng;
    $replace = $lgSec;
    $text = $val;
    for($i=0; $i<count($text); $i++) {
        for($j=0; $j<count($find); $j++) {
            if($text[$i]==$find[$j]) {
                $tmp=$replace[$j]; //- don't need array here but string
                }
            }
        }
    $body = '<td>'.str_replace($corEng,$corSec,$tmp).'</td>';
    for($i = 1; $i < sizeof($val); $i++){    //- All of these are numbers
        $body .= '<td>'.$val[$i].'</td>';}
    $tbody .= "\t<tr>".$body."</tr>\n";
    $body = '';
}

The way 'IF strings are the same do replace' works better that simple str_replace but it is additional operation and execution will be slower. DB countries has 255 elements and those text of me about 200 so 200 times we are doing 255 checking and replacement or just replacement... Because second loop is neccessary anyway, I'll stand with simple str_replace.
IPB Image
ZIP Countries
http://www.laban.rs/files/Samples.zip


QUOTE(Dag @ Apr 9 2020, 08:18 PM) *

Will you retry with my samples?

QUOTE(Christian J @ Apr 9 2020, 03:10 PM) *

QUOTE(Christian J @ Apr 8 2020, 11:38 PM) *

but for some reason it returns this:

CODE
Array
(
    [0] => foo
    [1] => BAR
    [2] => foobar
)

[1] and [2] are what I expected, but shouldn't [0] be uppercase FOO? Haven't done any PHP in a long time. unsure.gif

I think I found the bug in my script above. The very first $j iteration works correct:

CODE
if($text[0]==$find[0]) // foo==foo

and does change "foo" to "FOO" in $textNew[0]. But in the next $j iteration:

CODE
if($text[0]==$find[1]) // foo!=bar

the IF compares "foo" with "bar", and because that's FALSE, $textNew[0] is changed again (this time by the ELSE condition) from "FOO" to the "foo" value of $text[0]).

This version might work better:

CODE
$find = array('foo', 'bar');
$replace = array('FOO', 'BAR');
$text = array('foo', 'bar', 'foobar');

$textNew=$text; // I first copy the whole array, only changing values later (if needed)

for($i=0; $i<count($text); $i++)
{
    for($j=0; $j<count($find); $j++)
    {
        if($text[$i]==$find[$j])
        {
            $textNew[$i]=$replace[$j]; // change array values only when needed (no need for ELSE condition)
        }
    }
}

echo '<pre>';
print_r($textNew);
echo '</pre>';



User is offlinePM
Go to the top of the page
Toggle Multi-post QuotingQuote Post

Reply to this topicStart new topic
1 User(s) are reading this topic (1 Guests and 0 Anonymous Users)
0 Members:

 



- Lo-Fi Version Time is now: 5th June 2020 - 05:06 PM