Avatar billede tipsen Nybegynder
28. juli 2003 - 17:59 Der er 14 kommentarer og
1 løsning

Substitution af tekst - vha. regulær expression.

Hej eksperter

Jeg skal have lavet noget tekstsubstitution af nogle data fra en database.

Haves:

array 1:
array(
  '1' => 'Fornavn1 Efternavn1',
  '3' => 'Fornavn2 Efternavn2',
  '6' => 'Fornavn3 Efternavn3',
  ...
);

array 2:
array(
  'meget lang tekst med mange sætninger og ord - 1',
  'meget lang tekst med mange sætninger og ord - 2',
  'meget lang tekst med mange sætninger og ord - 3',
  ...
);

Det jeg gerne vil have er at teksten i array 2 bliver søgt i gennem efter matches med navne fra array 1.

Hvis navnet 'Fornavn1 Efternavn1' bliver fundet i en tekst i array 2, skal det udskiftes med dette link:

<a href="http://www.server.dk/?cid=$cid&pid=$pid" title="Blabla Fornavn1 Efternavn1 blabla">Fornavn 1 Efternavn1</a>

hvor $pid skal være det indeks i array 1, som matcher 'Fornavn1 Efternavn1' - i dette tilfælde er pid=1.

Der gælder at alle elementer i array 2 skal gennemløbes og checkes op mod alle elementer fra array 1.

Håber forklaringen er til at forstå - spørg, hvis der er tvivl.

Det er vigtigt at løsningen er rimelig efficient, da det er data som genereres on the fly.

Problemet kan vist nemmest beskrives som at slå alle ord i en tekst op i en ordbog og derefter lave links på alle de ord der blev fundet. (Dette er også bare en eksempelforklaring og ikke det aktuelle tilfælde!)

Jeg vil selv gætte på, at det måske er spørgsmål om at generere en reg.exp udfra indholdet i array 1 og derefter køre elemeneterne i array 2 op imod denne reg.exp - men det er bare et gæt! (Jeg stinker lidt til det dér med regulære expressions...)

Håber I kan hjælpe.

Mvh

tipsen
Avatar billede detox Nybegynder
28. juli 2003 - 18:32 #1
Måske kan du bare bruge en str_replace. Hvad med $cid?
Avatar billede detox Nybegynder
28. juli 2003 - 18:33 #2
Eks:
----
<?
$pid = 0;
$arr1 = array ('Hans Jensen', 'Bent Hansen');
$arr2 = array ('meget lang tekst med mange sætninger og ord Hans Jensen', 'meget lang tekst med mange sætninger og ord Bent Hansen');
foreach ($arr1 as $str) {
    $pid++;
    foreach ($arr2 as $text) {
        if (strstr($text, $str)) {
            $new_arr2[] = str_replace($str, "<a href='http://www.server.dk/?cid=$cid&pid=$pid' title='Blabla $str blabla'>$str</a>", $text);
        }
    }
}
?>
Avatar billede tipsen Nybegynder
28. juli 2003 - 18:40 #3
detox: Jeg tror at str_replace bliver væsentligt langsommere end en godt formuleret regulær expression. $cid er en eksisterende variabel som har en værdi i forvejen.
Avatar billede detox Nybegynder
28. juli 2003 - 18:43 #4
Tja, det har du sikkert ret i. Særligt når den skal lave et if tjek først.
Avatar billede squashguy Nybegynder
28. juli 2003 - 18:44 #5
<?php
$array1 = array(
  '1' => 'Fornavn1 Efternavn1',
  '3' => 'Fornavn2 Efternavn2',
  '6' => 'Fornavn3 Efternavn3'
);

$array2 = array(
  'meget lang tekst med Fornavn1 Efternavn1 mange sætninger og ord - 1',
  'meget lang tekst med Fornavn2 Efternavn2 mange sætninger og ord - 2',
  'meget lang tekst med Fornavn3 Efternavn3 mange sætninger og ord - 3'
);


foreach($array1 as $pid => $navn){
    $link = "<a href='http://www.server.dk/?cid=$cid&pid=$pid'".
        "title='Blabla $navn blabla'>$navn</a>";

    for($i=0; $i < count($array2); $i++){
        //$array2[$i] = ereg_replace($navn, $link, $array2[$i]); // regulær hvis du vil
        $array2[$i] = str_replace($navn, $link, $array2[$i]);
    }
}

foreach($array2 as $text) echo $text."<br>";
?>
Avatar billede tipsen Nybegynder
28. juli 2003 - 18:45 #6
Derudover er $pid ikke nødvendigvis fortløbende.
Avatar billede detox Nybegynder
28. juli 2003 - 19:14 #7
Har rettet det med $pid. Den er nu hurtigere end man skulle tro, kun ca. 0,5 sek. for 10.000 gennemløb.
-------------------------
<?

$cid = "NOGET";
$array1 = array(
  '1' => 'Fornavn1 Efternavn1',
  '3' => 'Fornavn2 Efternavn2',
  '6' => 'Fornavn3 Efternavn3'
);
$array2 = array(
  'meget lang tekst med Fornavn1 Efternavn1 mange sætninger og ord - 1',
  'meget lang tekst med Fornavn2 Efternavn2 mange sætninger og ord - 2',
  'meget lang tekst med Fornavn3 Efternavn3 mange sætninger og ord - 3'
);

function getmicrotime(){
    list($usec, $sec) = explode(" ",microtime());
    return ((float)$usec + (float)$sec);
    }

$time_start = getmicrotime();
for ($c=0;$c<10000;$c++) {

foreach ($array1 as $pid => $str) {
    foreach ($array2 as $text) {
        if (strstr($text, $str)) {
            $new_arr2[] = str_replace($str, "<a href='http://www.server.dk/?cid=$cid&pid=$pid' title='Blabla $str blabla'>$str</a>", $text);
        }
    }
}
}
$time_end = getmicrotime();
echo $time_end - $time_start;
?>
Avatar billede tipsen Nybegynder
29. juli 2003 - 20:18 #8
detox og squashguy - læg et svar!

Jeg benyttede en kombi, hvor jeg droppede den regulære expression - når der nu alligevel ikke var behov for den :-) - og så fodrede jeg i stedet str_replace med arrays af search- og replacetekst - det er væsentligt hurtigere at kalde den én gang med to arrays som input i stedet for at kalde den flere gange med enkeltelementer.
Avatar billede detox Nybegynder
29. juli 2003 - 20:41 #9
Ja, det lyder som en fornuftig løsning, den med at bruge array's. Man kunne vel ikke se et eksempel?
Avatar billede detox Nybegynder
29. juli 2003 - 20:52 #10
Har gennemskuet den. Og ja den er ca. 3 gange så hurtig. Genialt!
Avatar billede detox Nybegynder
29. juli 2003 - 20:57 #11
Faktisk nærmere 4 x så hurtig!
Avatar billede tipsen Nybegynder
29. juli 2003 - 21:20 #12
detox: Du må hjertens gerne se koden, men det er bare pakket ind i alt muligt andet lige nu - så jeg tror næsten at ovenstående giver et bedre overblik og jeg har ikke lige tid til at omskrive den her til Eksperten, så det essentielle fremgår.
Avatar billede detox Nybegynder
29. juli 2003 - 21:27 #13
Fandt ud af det. Jeg lavede selv et eksempel, så hvis andre skulle være interesseret:
---------------
<?
$cid = "NOGET";
$arr1 = array(
  '1' => 'Fornavn1 Efternavn1',
  '3' => 'Fornavn2 Efternavn2',
  '6' => 'Fornavn3 Efternavn3'
);
$arr2 = array(
  'meget lang tekst med Fornavn1 Efternavn1 mange sætninger og ord - 1',
  'meget lang tekst med Fornavn3 Efternavn3 mange sætninger og ord - 3',
  'meget lang tekst med Fornavn2 Efternavn2 mange sætninger og ord - 2'
);
foreach ($arr1 as $pid => $str) {
    $rep[] = "<a href='http://www.server.dk/?cid=$cid&pid=$pid' title='Blabla $str blabla'>$str</a>";
}
$new_arr2[] = str_replace($arr1, $rep, $arr2);
foreach ($new_arr2 as $my) {
    foreach ($my as $new) {
        echo $new . "<br>";
    }
}
?>
Avatar billede detox Nybegynder
29. juli 2003 - 21:30 #14
Men jeg vil ikke have point, det er nærmere mig der skal give dig nogen, for at henlede min opmærksomhed på str_replace()'s geniale funktionalitet!
Avatar billede tipsen Nybegynder
01. august 2003 - 16:57 #15
Lukket og slukket - tak for hjælpen.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester