Ein Wort in RegExp ausschließen?
PoWl24
- perl
Hi!
Ich möchte mit meinem Regulären ausdruck ein Wort ausschließen. Und zwar bezwecke ich damit innerhalb einer verschachtelten html struktur immer nur das innerste element zu erkennen.
<div id=1>
<div id=2>
<div id=3>
</div>
</div>
</div>
das soll zum beispiel nach dem schema ersetzt werden: [divID][/divID]
mit einem herkömmlichen regexp hätte das aber zur folge dass das so aussieht:
[div1]
[div2]
[div3]
[/div1]
[/div2]
[/div3]
das liegt daran dass immer die kleinste menge genommen wird, das muss auch so sein, allerdings darf in dieser menge keine andere anweisung sein da er sonst das </div> nicht richtig zuordnen kann.
Wenn ich ihm nicht befehle immer die kleinste Menge zu nehmen kriege ich hiermit probleme:
<div id=1></div><div id=2></div>
da kommt dann sowas raus:
[div1]</div><div id=2>[/div2]
auch nix.. Also muss meine anweisung sein.. immer die kleinste menge also z.b. (.+?) aber ohne <div.*>.. Das hat zur folge dass er die divs immer von innen heraus versucht abzubauen, ich führe den replace einfach so oft aus wie er noch matches findet.
Warum ich nicht einfach [^<>] nehmen kann..
<div id=1>
<div id=2>
<div id=3>
<b>Bla</b>
</div>
</div>
</div>
Das innerste Div wird hier garnicht erkannt.
Hat jemand also ne ahnung wie ich ein Wort Ausschließen kann?
Ein netter user hat sich letztens schon die mühe gemacht und mir ein super beispiel geproggt um das über DOM zu machen aber das ist leider nich so praktikabel da der IE alle zeilenumbrüche killt^^, klar das lässt sich auch umgehen aber die lösung mit dem regexp find ich für mich schöner und übersichtlicher
mfg PoWl
Moin!
Ein netter user hat sich letztens schon die mühe gemacht
;-) Danke.
Mit Regular Expressions wirst Du hier aber nicht weiter kommen. Dir wird wohl nix übrig bleiben, als selbst zu parsen:
<html>
<head>
<script language="JavaScript" type="text/JavaScript" >
var token, pos;
function bbcode() {
token= document.mainform.eingabe.value.match( /(<[^>]+>|[^<]+)/g );
pos= 0;
document.mainform.ausgabe.value= convert_to_bbcode();
}
function convert_to_bbcode( end_tag ) {
var result= '';
while ( pos < token.length ) {
var t= token[ pos++ ];
if ( t.charAt(0) == '<' ) {
var tagname= t.replace( /^<([^\s>]+).*/ , '$1' );
if ( tagname == end_tag ) return result;
switch (tagname) {
case 'div':
var align= t.replace( /^.*\balign="([^"]+)".*/, '$1' );
result+= '[' + align.toUpperCase() + ']' + convert_to_bbcode( '/div' ) + '[/' + align.toUpperCase() + ']';
break;
case 'b':
result+= '[b]' + convert_to_bbcode('/b') + '[/b]';
break;
default:
result+= ' ?? ' + t + ' ?? ';
break;
}
}
else {
result+= t;
}
}
return result;
}
</script>
</head>
<body>
<form method="post" name="mainform" action="http://www.google.de/" onsubmit="return false;">
<textarea id="eingabe" cols="75" rows="10">
<b>
bold
<div align="left">
left
<div align="right">
right
<div align="center">
center
</div>
</div>
</div>
</b>
</textarea>
<button onclick="bbcode()">mach</button>
<textarea id="ausgabe" readonly cols="75" rows="10"></textarea>
</form>
<div id="blinddiv"></div>
</body>
</html>
... nur mal so ins Unreine fantasiert...
-- Skeeve
Danke für das 2. Beispiel.
Ich versuche es damit einfach mal, was du mir sagen willst ist wohl dass es mit Regexp keine möglichkeit gibt herauszufinden ob in einer zeichenmenge das wort <div.*> vorkommt hm?
Wieso eigentlich? Ich find das ein großes manko.
mfg PoWl
Moin!
Ich versuche es damit einfach mal, was du mir sagen willst ist wohl dass es mit Regexp keine möglichkeit gibt herauszufinden ob in einer zeichenmenge das wort <div.*> vorkommt hm?
Doch. Klar. Das wäre ja nur ein /<div.*>/.
Was Du haben willst, ist ein Ausdruck, der bei <div.*> beginnt, alles findet, was nicht <div.*> enthält und mit </div> endet.
Dies könnte klappen:
/<div[^>]*>(?:[^<]+|<[^d][^<>]*>|<d[^i][^<>]*>]<di[^v][^<>]*>]|<div[^>\s])*?</div>/
Wieso eigentlich? Ich find das ein großes manko.
So sind sie halt, die regulären Ausdrücke.
-- Skeeve
Moin!
Ups! Das sollte ja PERL sein! Oder war das ein Versehen?
Wenn es um Perl geht, dann nimm lieber einen echten Parser. Wäre es XML würde ich XML::Twig vorschlagen. Für HTML Parsing gibt es sicherlich auch schöne Module.
Oder schau mal mein Posting bei den Perlmonks an: Tokenizing XML
-- Skeeve
Hey,
reguläre Ausdrücke sind hier das falsche Werkzeug.
#!/usr/bin/perl
use strict;
use diagnostics;
use HTML::TokeParser::Simple;
my $parser = HTML::TokeParser::Simple->new(string => <<'');
<div id=1>
<div id=2>
<div id=3>
</div>
</div>
</div>
my @idstack;
while (my $tag = $parser->get_tag) {
if (
(ref $tag eq 'HTML::TokeParser::Simple::Token::Tag::Start')
and
($tag->get_tag eq 'div')
and
(defined $tag->get_attr->{id})
) {
print '[div'.$tag->get_attr->{id}.']';
push @idstack, $tag->get_attr->{id};
next;
} elsif (
(ref $tag eq 'HTML::TokeParser::Simple::Token::Tag::End')
and
($tag->get_tag eq 'div')
) {
my $id = pop @idstack;
print '[/div'.$id.']';
next;
};
print $tag->as_is;
};
Die Edgecases zu behandeln ist deine Hausaufgabe.