regexp hilfe

regexp hilfe

am 08.11.2006 11:41:11 von Bodo Malo

Hallo


Ich habe diesen code von einer script seite
Es geht darum in einem Text bestimmte Wörter (array target) mit Links
zu hinterlegen. Aber die Austauschfunktion ist case-sensitiv, und das
macht
sie etwas ineffektiv in diesem Fall (manche Leute schreiben die Wörter
groß, manche klein, denn es handelt sich um Songtitel)

$map =3D array();
foreach ($targets as $k =3D> $v){
$key2use =3D preg_quote($k);
$map[$key2use] =3D sprintf(' href=3D"%s">%s', $k, $v, $k);
}
uksort($map, 'cmp');
$tmp =3D '(\b'.join ('\b|\b', array_keys($map)).'\b)';
$regexp =3D "/".$tmp."(?![^<]+>)/ie";
//echo $regexp;
$new =3D preg_replace($regexp,'gimmeTheLink("\1", $map)',$text);

Ich habe herausgefunden das man mit dem Modifiere 'i' die regexp
case-insensitive machen kann, jedoch weiß ich nicht wo genau man das
plazieren muß (ich kenne mich mit regular expressions nicht wirklich
aus). Dort wo es jetzt steht /ie hat es keine Wirkung.
Kann mir jemand helfen und das i richtig plazieren?

Danke
Malo

Re: regexp hilfe

am 08.11.2006 11:58:30 von Holger Pollmann

"Bodo Malo" schrieb:

> Ich habe diesen code von einer script seite
> Es geht darum in einem Text bestimmte Wörter (array target) mit
> Links zu hinterlegen. Aber die Austauschfunktion ist case-sensitiv,
> und das macht sie etwas ineffektiv in diesem Fall (manche Leute
> schreiben die Wörter groß, manche klein, denn es handelt sich um
> Songtitel)

Davon abgesehen, daß anscheinend die Variable $targets heißt und nicht
$target: wie ist dieser Array aufgebaut? Insbesondere: was ist da Key und
was ist Value?

> $map = array();
> foreach ($targets as $k => $v){
> $key2use = preg_quote($k);
> $map[$key2use] = sprintf(' > href="%s">%s', $k, $v, $k);
> }
> uksort($map, 'cmp');
> $tmp = '(\b'.join ('\b|\b', array_keys($map)).'\b)';
> $regexp = "/".$tmp."(?![^<]+>)/ie";

Dieser reguläre Ausdruck müßte an und für sich case-insensitive sein.

> //echo $regexp;
> $new = preg_replace($regexp,'gimmeTheLink("\1", $map)',$text);

Das da sollte eigentlich nicht funktionieren, weil da eigentlich \\1
stehen müßte. Oder $1. Sonderlich elegant finde ich es auch nicht...

> Ich habe herausgefunden das man mit dem Modifiere 'i' die regexp
> case-insensitive machen kann, jedoch weiß ich nicht wo genau man das
> plazieren muß (ich kenne mich mit regular expressions nicht wirklich
> aus). Dort wo es jetzt steht /ie hat es keine Wirkung.
> Kann mir jemand helfen und das i richtig plazieren?

Gib mal ein Beispiel dafür, wie der Array $targets aussehen könnte.

--
( ROT-13 if you want to email me directly: uvuc@ervzjrexre.qr )
"Sie tragen Trauer? Der Untergang der DDR?" - "Nein, Leni Riefenstahl.
Der Führer hat sie zu sich genommen." -- Abschiedsshow Scheibenwischer,
02.10.2003

Re: regexp hilfe

am 08.11.2006 19:40:30 von Bodo Malo

>
> Davon abgesehen, daß anscheinend die Variable $targets heißt und nicht
> $target: wie ist dieser Array aufgebaut? Insbesondere: was ist da Key und
> was ist Value?

Hi, okay hier ein paar Beispiele für das array, es sind nur relative
urls als Ziel, spielt sich alles innerhalb der Seite ab:

"Cecilia" =3D> "../PHP/showsongtab.php?id=3D10",
"Mrs. Robinson" =3D> "../PHP/showsongtab.php?id=3D15",
"Steve Gadd" =3D> "../PHP/musician.php?id=3D1",



> > $regexp =3D "/".$tmp."(?![^<]+>)/ie";
>
> Dieser reguläre Ausdruck müßte an und für sich case-insensitive s=
ein.

Tja, aber es funktioniert nicht wirklich wie man hier sieht.
http://www.paul-simon.info/PHP/showthread.php?thread=3D3153


> > //echo $regexp;
> > $new =3D preg_replace($regexp,'gimmeTheLink("\1", $map)',$text);
>
> Das da sollte eigentlich nicht funktionieren, weil da eigentlich \\1
> stehen müßte. Oder $1. Sonderlich elegant finde ich es auch nicht...

-- tja, das kann ich nicht sagen, aber es funktioniert.



Gruß
Malo

Re: regexp hilfe

am 08.11.2006 20:27:58 von Holger Pollmann

"Bodo Malo" schrieb:

>>> $regexp = "/".$tmp."(?![^<]+>)/ie";
>>
>> Dieser reguläre Ausdruck müßte an und für sich case-insensitive s
>> ein.
>
> Tja, aber es funktioniert nicht wirklich wie man hier sieht.
> http://www.paul-simon.info/PHP/showthread.php?thread=3153

Nein, er funktioniert richtig.

Das Problem leigt woanders:

$new = preg_replace($regexp,'gimmeTheLink("\1", $map)',$text);

Die Funktion gimmeTheLink wird vermutlich in etwa in dieser Art udn
Weise aus $map den Link holen:

function gimmeTheLink($key, $map)
{
return $map[$key];
}

oder?

Das Problem: die Schlüssel in dem Array $map sind die Bandnamen so, wie
sie sein sollen, also bspw. "Cecilia". Die Leute sollen im Text aber
auch "cecilia" schreiben können; wenn jemand das tut, dann matcht die
RegEx, ABER wenn denn der Begriff "cecilia" durch den entsprechenden
Link aus $map ersetzt werden soll, wird eben nach $map['cecilia']
gesucht und nicht nach $map['Cecilia']. Ergebnis ist, daß dann ein
leerer String zurückgegeben wird, so daß natürlich kein Link eingesetzt
wird.

Ein Quickhack wäre

function gimmeTheLink($key, $map)
{
foreach($map as $k => $v){
if(!strcasecmp($k, $key))
return $v;
}
return '';
}

aber das dürfte auf Dauer sehr zeitintensiv sein. Auf Anhieb fiele mir
da nur ein, die Keys im Array $map alle in Kleinbuchstaben umzuwandeln:

foreach ($targets as $k => $v){
$key2use = strtolower(preg_quote($k));
$map[$key2use] = sprintf('%s
', $k, $v, $k);
}

und dann in gimmeTheLink mit dem übergebenen $key das gleiche zu tun:

function gimmeTheLink($key, $map)
{
return $map[strtolower($key)];
}

Das dürfte deutlich weniger zeitintensiv sein. Und da eh die
Schreibweise egal sein sollte, macht das dann auch nichts, denn in
$targets kannst du dann ja gar nicht "Cecilia" und "cecilia" stehen
haben.

--
( ROT-13 if you want to email me directly: uvuc@ervzjrexre.qr )
"Das saarl. VwVfG läßt eine Interpretation deutscher Gesetze nur dann
zu, wenn sie nicht eindeutig sind." Manfred Saar, Präsident
Apothekerkammer d. Saarlandes. heute-journal v. 8. August 2006.

Re: regexp hilfe

am 13.11.2006 21:31:00 von Bodo Malo

> aber das dürfte auf Dauer sehr zeitintensiv sein. Auf Anhieb fiele mir
> da nur ein, die Keys im Array $map alle in Kleinbuchstaben umzuwandeln:
>
> foreach ($targets as $k =3D> $v){
> $key2use =3D strtolower(preg_quote($k));
> $map[$key2use] =3D sprintf(' >%s
>
', $k, $v, $k);
> }
>
> und dann in gimmeTheLink mit dem übergebenen $key das gleiche zu tun:
>
> function gimmeTheLink($key, $map)
> {
> return $map[strtolower($key)];
> }

Hi

Habe das jetz mal so gemacht, zwar nicht mit strtolower sondern mit
ucwords (aber das ist mehr wegen der Optik, denn so waren alle Links
plötzlich klein geschrieben).

gimmeTheLink sieht so aus
function gimmeTheLink($k, &$map)
{
$r =3D '';
if (isset($map[ucwords($k)])){
$r =3D $map[ucwords($k)];
unset($map[ucwords($k)]); //nur 1 Ergebnis notwendig im
gesamten Text, daher unset
}
else{
$r =3D $k;
}
return $r;
}

Danke für die Hilfe

Re: regexp hilfe

am 14.11.2006 00:53:14 von Holger Pollmann

"Bodo Malo" schrieb:

> Habe das jetz mal so gemacht, zwar nicht mit strtolower sondern mit
> ucwords (aber das ist mehr wegen der Optik, denn so waren alle
> Links plötzlich klein geschrieben).

Das ist m.E. kein sonderlich sinnvoller Grund, denn: die Keys im $map-
Array werden nur als Lookup benutzt, aber gar nicht im erzeugten Text
ausgegeben. Der Text, der ausgegeben wird, wird nämlich vorher aus dem
Array $targets erzeugt, und in dem stehen die Künstler so drin, wie sie
auch geschrieben werden sollen.

Ob's Performance-mäßig einen Unterschied macht, weiß ich nicht.

Einfacher wäre in gimmeTheLink() übrigens folgendes:

$r = $map[ucwords($k)];
$map[ucwords($k)] = $k;

--
( ROT-13 if you want to email me directly: uvuc@ervzjrexre.qr )
"Das saarl. VwVfG läßt eine Interpretation deutscher Gesetze nur dann
zu, wenn sie nicht eindeutig sind." Manfred Saar, Präsident
Apothekerkammer d. Saarlandes. heute-journal v. 8. August 2006.