regex
-
ich ab einen text der art
text
tokenA value1
text
tokenA value2
text
tokenB
text(und das ganze zig mal, "text" ist nicht immer das gleiche, die anzahlen von tokenA zwischen den tokenB variieren, zeilenumbrueche sind hier nur fuer die uebersichtlichkeit)
nun will ich per regex dafuer sorgen, dass in diesem beispiel hinter tokenB value2 eingefuegt wird, allgemein immer hinter einem tokenB der value vom tokenA _unmittelbar_ davor.
ich kriegs nur hin, dass er mir hier alles vom ersten tokenA bis tokenB matcht, und dann natuerlich value1 hinter tokenB schreibt.
(tokenA[\s\S]+?value=")(.?)("[\s\S]?tokenB) reicht also nicht.
vermutlich muss irgendwie ein negative lookahead (?![\s\S]*tokenA[\s\S]*) da rein, aber ich habs nicht korrekt hinbekommen, weil dieser ja nicht einfach beim naechsten tokenB aufhoert, auch nicht, wenn man ihn lazy macht.die frage wuerde sich stark vereinfachen, wenn man per regex ein nicht-matchen ausdruecken koennte, aber das geht nur characterweise, oder?
-
ich habe die erfahrung gemacht das regexp sich nur für einfache aufgaben eignen, wer damit mehr machen will behindert sich nur selbst
irgend wann kommt der punkt an den man AND NOT OR IF WHILE in den regexp braucht, du hast die wahl,
- du machts einige workarounds
- du wartest bis jemand regexp rausbringt die das können
- du benutzt die programiersprache für
ich tendiere stark zu punkt 3, du hast viel mehr macht, das ganze ist lesbar und wartbarer, es ist natürlich nicht so leet wenn nicht alles in eine zeile zusammengequetscht ist

-
ich war grad am find&replace in eclipse benutzen.
dachte mir, das muesste gehen, ohne extra nen programm dafuer zu schreiben.
inzwischen hab ichs halb-haendisch gemacht, war nicht soviel.
an einer loesung bin ich trotzdem weiter interessiert.
bedeutet dein post, dass du weisst, dass es nicht geht, oder dass du die einfach nichts magst?
-
ja es geht du musst ihn nur sagen das er 'unhungrig' sein soll, http://tut.php-q.net/regex.html#u11
-
dieses "unhungrig" nennt sich lazy und ich habe bereits erwaeht, dass ich es trotzdem nicht hinbekommen habe.
ein expliziter ausdruck, der deiner meinung nach funktioniert, waere nett.
-
ok dann will ich aber auch mehr arbeit von dir sehen,
-welche regexp implementierung?
-wie sehen die strings aus, nicht die vereinfachte version?
-zeige mir strings bei den es keine probleme gibt und welche bei den es probleme gibt
-erkläre genau wie du vorgegangen bist und wie du dir das ganze gedacht hast schritt für schritt
-was hast du dir z. B. bei [\s\S] gedacht?
-
obwohl das alles schon vorkam, werde ich es nochmal neu strukturieren, ich hoffe es bringt was.
ad 1) wie schon erwaehnt erwuchst die frage aus den regexps von der eclipse suchfunktion. die frage stelle ich mir aber abstrakter. wie die loesung in einer konkreten syntax aussieht, ergibt sich dann schon.
ad 2) wie die aussehen, tut nix zur sache, denn ich will keine loesung durch ausschliessen von characterklassen, das kaeme mir wie ein boeser hack vor.
....
tokenA value="v1"
....
tokenA value="v2"
....
tokenB
....aus tokenB soll nachher tokenB_v2 werden.
ad 3)
bei
....
tokenA value="v2"
....
tokenB
....
gibts keine probleme, da zwischen dem ersten tokenA und tokenB kein weiteres tokenA vorkommt.
beim beispiel aus 2) gibts probleme, ich erhalte tokenB_v1.ad 4)
das unter 3) gesagt bezieht sich auf den ansatz (tokenA[\s\S]+?value=")(.?)("[\s\S]+?tokenB) ersetzen durch $1$2$3_$2.
um zu vermeiden, dass noch ein tokenA dazwischen ist, dachte ich, ich sollte in der dritten gruppen vor tokenB statt nur dem blinden faulen allesfresser noch einen negativen lookahead einbauen, etwa so (?![\s\S]*tokenA[\s\S]*), das funzt aber nicht, und ich vermute deshalb nicht, weil der damit auch tokenA's findet, die schon nach dem naechsten tokenB kommen.
ebenfalls versucht habe ich ((tokenA[\s\S]+?value=")(.?)("[\s\S]+?)){1}(tokenB), wenn ich mich recht erinnere, und das hat auch nicht geholfen, damit kann man offenbar mehrere vorkommen von tokenA erzwingen (wenn man die 1 erhoeht), aber keine ausschliessen.ad 5) \s sind spaces und \S sind non-spaces, zusammen also beliebige chars, weil . zumindest keine zeilenumbrueche erfasst.
-
eclipse wird wohl java benutzen
Special constructs (non-capturing) sieht intersant aus
http://java.sun.com/j2se/1.5.0/docs/api/java/util/regex/Pattern.htmlunter php kannst du php code in die regexp packen (d.h. if usw.) oder preg_replace_callback benutzen
wenn du standard regexp benutzen willst kannst du den text einmal umdrehen und dan nach Bnekot suchen
-
hier ist noch ein trick http://www.lrz-muenchen.de/services/schulung/unterlagen/regul/regul-11.html#paren
-
im trick kann ich nichts nuetzliches erkennen, dass ich vermute, dass es mit lookaheads gehen koennte, sagte ich bereits, und haette gern gewusst, wie genau.
wenn php code drin vorkommt, ist es fuer mich kein regex mehr.
das mit dem umdrehen klingt interessant. geht das in einem ausdruck, oder muss ich
1. text replacen durch den umgedrehten
2. ersetzen
3. text replacen durch den umgedrehten
?
-
PeterTheMaster schrieb:
im trick kann ich nichts nuetzliches erkennen,
ich hatte nur so ein gefühl das es damit gehen kann
PeterTheMaster schrieb:
dass ich vermute, dass es mit lookaheads gehen koennte, sagte ich bereits, und haette gern gewusst, wie genau.
das müssen dir die java junger oder die verlinkte docu verraten
PeterTheMaster schrieb:
das mit dem umdrehen klingt interessant. geht das in einem ausdruck, oder muss ich
1. text replacen durch den umgedrehten
2. ersetzen
3. text replacen durch den umgedrehten
?ich habe es nicht ganz verstanden was du meinst, ich meine du drehst deinen text um
austext tokenA value1 text tokenA value2 text tokenB textwird dann
txet Bnekot txet 2value Anekot txet 1value Anekot txetund deine regexp schreibs du so
(Benkot[\s\S]*?")(.*?)("=value[\s\S]+?Anekot)
-
jup, das letzte sind zwar leider 3 schritte, nicht ein eleganter ausdruck, aber so sollte das machbar sein. gute idee. danke.
moment, geht das umdrehen des textes ueberhaupt durch ein regex replacement? oder muesst ich da schonwieder mit nem extra programm ran?