ReExp
Tim Walter
- perl
Hallo Liste
ich habe eine csv Datei in art eines baums, wo aber leider einige verzweigungen doppelt sind.
sieht etwa so aus:
doof;test1;test1;drei
test2;test2;hans;hans;vier
test3;test3;test3;fuenf
test4;test4;hans;peter
karl;tut;tut;lisa
tim;tim ist doof
mein plan ist jeztt die datei zu durchlaufen und alle n-fachen zu entfernen. ergebnis sollte sein:
doof;test1;drei
test2;hans;vier
test3;fuenf
test4;hans;peter
karl;tut;lisa
tim;ist doof
aber ich hab da mit meinen lösungen noch nicht so den erfolg gehabt.
bei der letzten zeile müsste man wohl auch bedenken, das er von hinten anfängt auszutauschen.
mein ansatz war so in der art:
$line=";".$line;
if($line=~m/(;[^;]+){2}/i)
{
$line=~s/$1//i;
}
der sammelt aber nur die doppelten weg und leider von vorne.
sieht dann nur so aus:
doof;test1;drei
test2;hans;hans;vier
test3;test3;fuenf
test4;hans;peter
karl;tut;lisa
tim ist doof
kann mir einer helfen, oder zumindest mal eine ordentliche (bitte deutschsprachige) Seite nennen, wo man in die irrsinnigen weissheiten des pattern matching eingeführt wird.
Danke ..
cu Tim
Hi,
kann mir einer helfen, oder zumindest mal eine ordentliche (bitte deutschsprachige) Seite nennen, wo man in die irrsinnigen weissheiten des pattern matching eingeführt wird.
Regular Expressions helfen Dir nicht, weil Du kein Muster suchst. Du möchtest die Daten inhaltlich analysieren. Hashes könnten Dir hierbei helfen.
Cheatah
Hi,
Regular Expressions helfen Dir nicht, weil Du kein Muster suchst. Du möchtest die Daten inhaltlich analysieren. Hashes könnten Dir hierbei helfen.
ich suche aber doch nach einem wiederkehrenden muster oder nicht. aber wenn ich da falsch liege werde ich das wohl klassisch schreiben.
schade..
cu tim
Hi,
ich suche aber doch nach einem wiederkehrenden muster oder nicht.
tust Du das? Wenn ja, dann habe ich Deine Use-Cases fehlinterpretiert. Nach meinem Verständnis suchst Du Dubletten.
Cheatah
Hi,
ich suche aber doch nach einem wiederkehrenden muster oder nicht.
tust Du das? Wenn ja, dann habe ich Deine Use-Cases fehlinterpretiert. Nach meinem Verständnis suchst Du Dubletten.
Eine Dublette ist doch ein Muster - da wiederholt sich etwas ...
(?<=^|;)([^;]+);\1(?=;|$)
d.h.: lookbehind: entweder Stringanfang oder Trennzeichen, danach ein Wert, danach ein Trennzeichen, danach nochmal derselbe Wert, danach ein lookahead auf Trennzeichen oder Stringende.
lookbehind + lookahead sind m.E. notwendig, da sonst zum Beispiel bei bla;aber eine Ersetzung zu blaber stattfinden würde.
(Falls es sich bei den Werten nur um "Wortzeichen" handeln kann, könnten es Wortgrenzen \b auch tun)
ersetzen durch \1
sollte m.E. Dubletten in semikolon-getrennten Werten entfernen (Voraussetzung: a;b;a;d gilt nicht, die doppelten Werte müssen aufeinanderfolgen - sonst wird's etwas aufwendiger)
Sollen auch noch häufigere Vorkommen in einem Durchgang miterledigt werden, müßte es mit
(?<=^|;)([^;]+)(?:;\1)+(?=;|$)
klappen.
cu,
Andreas
gudn tach!
tust Du das? Wenn ja, dann habe ich Deine Use-Cases fehlinterpretiert. Nach meinem Verständnis suchst Du Dubletten.
Eine Dublette ist doch ein Muster - da wiederholt sich etwas ...
rischdisch.
(?<=^|;)([^;]+);\1(?=;|$)
vorsicht, das funzt nicht...
fuehrt naemlich zu
"Variable length lookbehind not implemented in regex[...]"
d.h.: lookbehind: entweder Stringanfang oder Trennzeichen
kann man durch doppelte negation erreichen:
(?<![^;])
in worten: "davor darf kein zeichen kommen, dass kein semikon ist."
[...] Dubletten
die schwierigkeit fuer den OP waren vor allem n-fache vorkommnisse fuer n>2.
prost
seth
Hi,
(?<=^|;)([^;]+);\1(?=;|$)
vorsicht, das funzt nicht...
fuehrt naemlich zu
"Variable length lookbehind not implemented in regex[...]"
kann man durch doppelte negation erreichen:
Oder durch zwei negative lookbehinds, einen für den Stringanfang, einen für das Trennzeichen ...
cu,
Andreas
gudn tach!
(?<=^|;)([^;]+);\1(?=;|$)
vorsicht, das funzt nicht...
fuehrt naemlich zu
"Variable length lookbehind not implemented in regex[...]"kann man durch doppelte negation erreichen:
Oder durch zwei negative lookbehinds, einen für den Stringanfang, einen für das Trennzeichen ...
¿zwei negative?
mach mal 'n beispiel.
prost
seth
Hi,
Oder durch zwei negative lookbehinds, einen für den Stringanfang, einen für das Trennzeichen ...
¿zwei negative?
Ich sollte so früh am Morgen nicht posten. Zwei positive natürlich.
cu,
Andreas
gudn tach!
Oder durch zwei negative lookbehinds, einen für den Stringanfang, einen für das Trennzeichen ...
¿zwei negative?Ich sollte so früh am Morgen nicht posten. Zwei positive natürlich.
¿zwei positive? ;-)
die wuerden einer UND-verknuepfung gleichkommen, aber nicht einer ODER-verknuepfung.
prost
seth
Hell-O!
Hashes könnten Dir hierbei helfen.
ich suche aber doch nach einem wiederkehrenden muster oder nicht.
Ich stimme Cheatah zu, dass Reguläre Ausdrücke hier nicht nötig sind. Eine Möglichkeit wäre, jede Zeile zu splitten, jeden einzelnen Eintrag als Hash-Schlüssel zu verwenden. Damit entfallen alle Mehrfacheinträge automatisch, da Hash-Schlüssel immer eindeutig sein müssen:
while(<DATEI>) {
# wir brauchen einen frischen Hash
my %unique;
# Hash-Slice mit den Einzelwerten
# Mehrfacheinträge verschwinden
@unique{ split(/;/, $string) } = ();
# Kontrollausgabe
print join ';', (keys %seen);
}
Statt der print-Anweisung kannst du die bereinigten Werte natürlich auch speichern oder gleich wegschreiben oder was immer du damit tun willst.
Siechfred
Hell-O Ingrid!
Bevor es jemand anderes merkt:
@unique{ split(/;/, $string) } = ();
Muss natürlich heißen:
@unique{ split(/;/, $_) } = ();
Siechfred
gudn tach!
Ich stimme Cheatah zu, dass Reguläre Ausdrücke hier nicht nötig sind.
er sagte nicht, dass sie nicht noetig seien, sondern, dass sie nicht helfen wuerden und lag damit falsch.
Eine Möglichkeit wäre, jede Zeile zu splitten, jeden einzelnen Eintrag als Hash-Schlüssel zu verwenden. Damit entfallen alle Mehrfacheinträge automatisch, da Hash-Schlüssel immer eindeutig sein müssen:
war auch mein erster gedanke, aber unter den vom OP genannten voraussetzungen bzgl. der verarbeitung von "tim;tim ist doof" wuerde das schon wieder eher haarig werden.
prost
seth
gudn tach!
sieht etwa so aus:
doof;test1;test1;drei
test2;test2;hans;hans;vier
test3;test3;test3;fuenf
test4;test4;hans;peter
karl;tut;tut;lisa
tim;tim ist doof
kommen etwaige mehrfache denn immer direkt hintereinander vor?
mein plan ist jeztt die datei zu durchlaufen und alle n-fachen zu entfernen. ergebnis sollte sein: [...]
tim;ist doof
bei der letzten zeile müsste man wohl auch bedenken, das er von hinten anfängt auszutauschen.
und was sollte im fall
tim ist doof;tim
passieren? nix? oder tritt sowas nicht auf?
mein ansatz war so in der art:
$line=";".$line;
if($line=~m/(;[^;]+){2}/i)
{
$line=~s/$1//i;
}
der sammelt aber nur die doppelten weg
bei diesem ansatz muesstest du dann bloss aus dem "if" ein "while" machen. (allerdings behebt das noch nicht die anderen probleme.)
und leider von vorne.
hmm, noe.
aus
tim;tim ist doof
matcht /(;[^;]+){2}/
$1=";tim ist doof"
je nach antwort auf meine oben gestellten fragen, wird dir evtl. die folgende variation deines ansatzes weiterhelfen:
for my $line (@lines){
$line=';'.$line.';';
#while($line=~/(;[^;]+)\1/i){
# $line=~s/($1)$1+./$1;/i;
#}
#oder u.u. besser mit posisionsmerker:
while($line=~/(;[^;]+)(?=\1)/ig){
$line=~s/\G$1+./;/i;
}
$line=substr($line,1,-1);
print $line."\n";
}
zumindest kommt damit fuer das gegebene beispiel genau das raus, was rauskommen soll.
kann mir einer helfen, oder zumindest mal eine ordentliche (bitte deutschsprachige) Seite nennen, wo man in die irrsinnigen weissheiten des pattern matching eingeführt wird.
ich kenne nichts gescheites auf deutsch. die deutschen seiten, die ich kenne, knabbern nur an oberflaechlichkeiten oder winzigen ausschnitten der details.
aber bei regexps ist imho das verstehen einer _englischen_ dokumentation vernachlaessigbar leicht im ggs. zum inhalt, also den regexps selbst.
naja, und versuche, sowas wie "zero-width negative look-behind assertion" gescheit zu uebersetzen sind imho schlichtweg zum scheitern verurteilt. "nach hinten blickende negativ-aussagen mit nulllaenge"?
isch glaub isch muss bresche!
iow: ok, etwas allumfassendes kann es gar nicht geben, aber auf englisch sind viel mehr nuetzliche information ueber regexps zu finden als auf deutsch. und weil regexps so toll sind, tendiere ich sogar zu der meinung, dass sie alleine grund genug sind, sich mal naeher mit der englischen sprache zu befassen, um sie besser studieren zu koennen.
trotzdem: ein sehr gutes buch soll die deutsche uebersetzung von "mastering regular expressions" (http://www.oreilly.de/catalog/regex2ger/) sein.
prost
seth