Text ersetzen - aber nicht innerhalb von Link-Tags

12/03/2012 - 01:38 von Sven Paulus | Report spam
Hi zusammen,

ich bin gerade ein wenig am Regex-Rumknobeln: Ich moechte gerne in einem
HTML-Dokument jedes Vorkommnis eines bestimmten Strings ersetzen, aber
nicht, wenn dieser String (irgendwo) innerhalb von einem a-Tag-Paerchen
steht.

Wenn ich z.B. als FOO mit BAR ersetzen wollte, dann soll folgendes
passieren:
FOO -> ersetzen
Hallo Du alter FOO! -> ersetzen
<b>FOO</b> -> ersetzen
<a href="...">FOO</a> -> nicht ersetzen
<a href="..."><b>FOO</b></a> -> nicht ersetzen
<a href="...">12 FOO 34</a> -> nicht ersetzen
<a href="..."><b>12 FOO 34</b></a> -> nicht ersetzen

Eigentlich alles soweit nicht tragisch, nur am letzten o.g. Beispiel
scheitere ich. Wenn ich in das negative look ahead fuer das
Schliessen das a-Tags ein ".*?" mit reinnehme, dann matcht alles
nicht mehr.

Z.Z. stehe ich hier:

| #! /usr/bin/perl
|
| $a = '<a href="http://www.example.org">FOO</a> FOO string oder anderer FOO <b>FOO</b> <a href="http://www.example.org"><...</a> <a href="http://www.example.org">Es ist FOO oder so</a> <a href="FOO">Anderer Link</a> <a href="http://www.example.org"><b>Aha - FOO string</b></a> FOO';
|
| $a =~ s/(?!<a[^>]+>)\bFOO\b(?!([^<]*|<[^>]+>)<\/a>)/BAR/g;
|
| print $a, "";

Das liefert mir

| <a href="http://www.example.org">FOO</a> BAR string oder anderer BAR <b>BAR</b> <a href="http://www.example.org"><...</a> <a href="http://www.example.org">Es ist FOO oder so</a> <a href="FOO">Anderer Link</a> <a href="http://www.example.org"><b>Aha - BAR string</b></a> BAR

Wie man sieht, eigentlich alles ganz ok, nur des vorletzte BAR sollte eben
so nicht sein ...

Hat jemand 'ne Idee, was ich anders machen koennte? Ja, klar, es gibt
fuer sowas auch geschicktere Loesungsmoeglichkeiten als regular expressions,
nur hat mich hier jetzt doch mal die Neugierde gepackt :)

Gruesse,

Sven
 

Lesen sie die antworten

#1 Tim Landscheidt
12/03/2012 - 04:18 | Warnen spam
Sven Paulus wrote:

[...]
Hat jemand 'ne Idee, was ich anders machen koennte? Ja, klar, es gibt
fuer sowas auch geschicktere Loesungsmoeglichkeiten als regular expressions,
nur hat mich hier jetzt doch mal die Neugierde gepackt :)



| $_ = $a;
| while (/(<a .*?<\/a>|FOO)/g)
| {
| substr ($_, pos () - length ($1), length ($1)) = 'BAR' if ($1 eq 'FOO');
| }

Irgendwie schaffe ich es aber nicht, die Zuweisung an $_
durch ein "$a =~" zu ersetzen. Wenn length ('FOO') != length
('BAR') müsste man wohl noch pos () zuweisen.

Tim

Ähnliche fragen