• Apfeltalk ändert einen Teil seiner Allgemeinen Geschäftsbedingungen (AGB), das Löschen von Useraccounts betreffend.
    Näheres könnt Ihr hier nachlesen: AGB-Änderung
  • Was gibt es Schöneres als den Mai draußen in der Natur mit allen Sinnen zu genießen? Lasst uns teilhaben an Euren Erlebnissen und macht mit beim Thema des Monats Da blüht uns was! ---> Klick

RegEx Problem

Slashwalker

Winterbanana
Registriert
15.05.06
Beiträge
2.213
RegEx waren noch nie mein Ding ;)
Ich brauch eine RegEx für folgende Situation:
Auf einer Website sollen Bilder/PDF hochgeladen werden. Diese sollen nach dem Upload duplizierbar sein.
Daher wird beim ersten duplizieren aus test.jpg test_copy_123456.jpg wobei 123456 für eine Art timestamp steht (tickcount), da dieser wirklich immer einzigartig ist.

Soweit so gut. Wenn ich jetzt das Bild test_copy_123456.jpg duplizieren will muss es ja wieder neu benannt werden.
Daher bräuchte ich eine RegEx, die genau den String _copy_ sowie [0-9] findet. Mit "_copy_[0-9]" funktioniert es nicht, ebensowenig mit "[_copy_0-9]". Zweitere würde zwar funktionieren, findet allerdings auch das p in jpg :(

Lässt sich sowas überhaupt mit RegEx bewerkstelligen? Any idea?
 

_linx_

Kleiner Weinapfel
Registriert
04.01.09
Beiträge
1.125
Code:
//([^_]*)_([^_]*)_([^_]*)/
 
Zuletzt bearbeitet:

Slashwalker

Winterbanana
Registriert
15.05.06
Beiträge
2.213
Geht leider nicht, da wird bei duplizieren von test_copy_123456.jpg ein test_copy_123456_copy_123456.jpg draus.

Ich muss glaub ich mal bissel mehr Infos rausrücken ;)

Code:
<cfset x=gettickcount()>
<cfset newname=rereplace(session.cfoshoppingcard.special[attributes.pid].img[attributes.dupliziere].name,"//([^_]*)_([^_]*)_([^_]*)/","","All")>

<cfset newname=listfirst(newname,".")&"_copy_"&x&"."&listlast(newname,".")>
<cffile action="rename" destination="#expandpath('.')#/uploads/#session.id#/#newname#" source="#expandpath('.')#/uploads/#session.id#/#session.cfoshoppingcard.special[attributes.pid].img[attributes.dupliziere].name#">

Zeile 1 setzt einen neuen Tickcount, der einmalig ist.
In Zeile 2 wird der in der Session gespeicherte Dateiname nach der RegEx durchsucht und diese entfernt.
In Zeile 3 wird der neue Name, der nun kein _copy_123456 mehr enthalten sollte, neu zusammengesetzt.
Hierzu wird der Name als Liste behandelt, deren Seperator der Punkt ist. Listfirst liefert also den Dateinamen und Listlast die Dateiendung. Dazwischen wird der String _copy_ und die Variable X eingefügt.
 

Steinchen

Finkenwerder Herbstprinz
Registriert
15.04.10
Beiträge
470
Hi,

wenn ich als Grundlage ein "test_123456.jpg" nehme und daraus dann ein "test_copy_123456.jpg" machen will stellt sich mir die Frage warum es kein "copy_test_12345.jpg" oder "test_12345_copy.jpg" sein kann. Antwort: Ist zu einfach ;)

Aber machs dir doch nicht so schwer, gibt auch einfacherer Lösungen:

Aus "test12345.jpg" wird "test_12345_copy.jpg":

Code:
$newfilename = basename("test_12345.jpg",".jpg") + "_copy.jpg";
Du kannst natürlich auch einfach mittels Regexp die Zahlen suchen, sowas z.B.:

"([:digit:]*)".

Funktioniert prima in sed:

Code:
mac:~ steinchen$ echo "test_123_bleh.jpg" | sed -E -e 's/([[:digit:]]*)//g'
test__bleh.jpg
mac:~ steinchen$
cu
 

Slashwalker

Winterbanana
Registriert
15.05.06
Beiträge
2.213
Hallo Steinchen, die Grundlage ist test.jpg nicht test_123456.jpg ;)
Das Problem ist, das auch Kopien von der Kopie der Kopie der Kopie ... möglich sein sollen. Daher auch der tickcount, damit sichergestellt ist dass es einen Dateinamen nur einmal geben kann. Dazu kommt natürlich noch, das ich vorher nicht weiß, wie die Dateien heißen werden, da diese von Usern hochgeladen werden.

Ziel ist also beim Beispiel test.jpg, das alle Kopien, egel ob direkt oder Kopie von der Kopie
test_copy_tickcount.jpg heißen sollen. Wobei tickcount eine Zahlenfolge ist, die im Prinzip dem Unix timestamp ähnelt und daher immer einzigartig ist.
 

drlecter

Wöbers Rambur
Registriert
04.11.06
Beiträge
6.442
Wie werden die Dateien denn hochgeladen? per PHP und Webinterface?
 

Slashwalker

Winterbanana
Registriert
15.05.06
Beiträge
2.213
ColdFusion und jQuery, da Multiupload. Aber die Technik ist ja erstmal zweitrangig. es fehlt an der passenden RegEx.
 

Steinchen

Finkenwerder Herbstprinz
Registriert
15.04.10
Beiträge
470
Hi,

ich glaub die Technik ist hier mitunter entscheidend. Ich würde mir einen Hash per Zufall erzeugen un diesen als Dateinamen benutzen. Auch bei Kopien o.ä. Damit umgehst du all deine Probleme.

Den Namen würde ich dann in der DB verlinken und fertig.

cu
 

Slashwalker

Winterbanana
Registriert
15.05.06
Beiträge
2.213
Also ich hab die RegEx jetzt zumindest soweit, das sie wirklich das vollständige wort sucht:
[(_copy_)0-9]

Allerdings müsste ich jetzt noch sagen können, das Zahlen nur nach dem Wort entfernt werden. Derzeit ist es so:
Aus IMG_0014.JPG wird beim duplizieren IMG_xl_copy_1274616989028.JPG. Es werden also alle Ziffern entfernt.
Wenn ich danach dann IMG_xl_copy_1274616989028.JPG dupliziere wird daraus IMG_xl_copy_1274616982771.JPG

Es scheitert nun also nur noch daran, dass alle Ziffern entfernt werden, statt nur derer, die auf _copy_ folgen.
 

Steinchen

Finkenwerder Herbstprinz
Registriert
15.04.10
Beiträge
470
Also ich hab die RegEx jetzt zumindest soweit, das sie wirklich das vollständige wort sucht:
[(_copy_)0-9]

Allerdings müsste ich jetzt noch sagen können, das Zahlen nur nach dem Wort entfernt werden. Derzeit ist es so:
Aus IMG_0014.JPG wird beim duplizieren IMG_xl_copy_1274616989028.JPG. Es werden also alle Ziffern entfernt.
Wenn ich danach dann IMG_xl_copy_1274616989028.JPG dupliziere wird daraus IMG_xl_copy_1274616982771.JPG

Es scheitert nun also nur noch daran, dass alle Ziffern entfernt werden, statt nur derer, die auf _copy_ folgen.

Hä?

Nur die Ziffern entfernen die auf Copy folgen und alle anderen stehen lassen? Wo in deinem Beispiel ist denn ein Name wo Ziffern *VOR* copy stehen.

Ich denke du hast hier ein hausgemachtes Problem das sich viel einfacher lösen lassen würde die das, was du da vor hast.

Einfach mal nicht um die Ecke denken hilft.

cu
 

Slashwalker

Winterbanana
Registriert
15.05.06
Beiträge
2.213
In IMG0014.JPG ? Daraus soll IMG0014_xl_copy_21364234.JPG werden. Es wird aber zu IMG_xl_copy_21364234.JPG.

Aber können wir nun aufhören über Sinn oder Unsinn meines Vorhabens zu diskutieren? Wie bekomme ich die RegEx so hin, das sie nur Zahlen die auf _xl_copy_ folgen erkennt?
 

_linx_

Kleiner Weinapfel
Registriert
04.01.09
Beiträge
1.125
Ich blick gar nicht mehr durch...

1. Wie ist das Schema der Datei, wenn du sie auf dem PC anwählst? [a]. vermutlich, oder?
2. Beim ERSTEN speichern auf dem Server wird die Datei zu welchem Schema? [a]_[tickcount].
3. Und dann willst du die Datei zu [a]_copy_[tickcount]. kopieren lassen?
4. Und die Datei aus 3 soll sich zu [a]_copy_copy_[tickcount]. kopieren lassen?

Erklär mir das bitte einmal ganz langsam.

p.s.: Du schaffst dir Probleme, das glaube ich gar nicht...

[...]
Aber können wir nun aufhören über Sinn oder Unsinn meines Vorhabens zu diskutieren? Wie bekomme ich die RegEx so hin, das sie nur Zahlen die auf _xl_copy_ folgen erkennt?

Code:
/(.*)_copy_([^_.]*)(.*)/
 

Slashwalker

Winterbanana
Registriert
15.05.06
Beiträge
2.213
Also noch mal ganz von vorne. Ein User läd von seinem Rechner eine Datei auf den Server. Wie diese Datei heißt weiß ich natürlich vorher nicht. Ich nenne sie jetzt mal test.jpg

Nach dem der User also test.jpg hochgeladen hat, will er diese duplizieren. Hierbei soll test_xl_copy_[tickcount].jpg raus kommen.
Wenn er diese nun nochmals dupliziert soll wieder eine test_xl_copy_[tickcount].jpg dabei raus kommen.

Das Problem ist eben, das der User auch eine IMG1234.jpg als Basis hochladen könnte. Solche Dateinamen sind ja bei Cams durchaus üblich. Meine RegEx würde jetzt beim duplizieren lieder auch das 1234 raus filtern, so dass dann IMG_xl_copy_[tickcount].jpg statt IMG1234_xl_copy_[tickcount].jpg raus kommt.

So, ich probier jetzt deine RegEx, mal sehen was dabei rauskommt.

Edit: Klappt leider auch nicht.
Original IMG_00145.JPG
Kopie IMG_00145_xl_copy_1274649568466.JPG
Kopie der Kopie IMG_00145_xl_copy_1274649568466_xl_copy_1274649576200.JPG
 

Swoop

Alkmene
Registriert
02.07.08
Beiträge
30
Hey ho. Probier mal folgende RegEx: (.*?)_copy_(\d+)\.(\w+)$
Wenn die matched weißt du, dass du es mit ner copy zu tun hast. dann ist der erste match der basisname, der zweite match dein tickcount und der dritte match die dateiendung. Bsp: test_copy_12345.jpg => ["test", "12345", "jpg"]

bei keinem match einfach den basename der datei nehmen und dein _copy_TICKCOUNT dran hängen.

im pseudocode:

Code:
wenn dateiname gg (.*?)_copy_(\d+)\.(\w+)$ matched
  neuer_dateiname = match(1) + "_copy_" + tickcount + "." + match(3)
sonst
  neuer_dateiname = basename(dateiname) + "_copy_" + tickcount + "." + dateiendung
ende
 

Steinchen

Finkenwerder Herbstprinz
Registriert
15.04.10
Beiträge
470
Hi,

boah was fürn hausgemachter Kram.

Ein User läd eine Datei hoch:

Es wird ein Hash erzeugt oder eine Zufallszahl mit md5 und dieser Wert wird als Dateiname auf der Platte genutzt:
Man könnte etwas über Datum,Uhrzeit plus ein paar bytes aus /dev/urandom nehmen, damit hat man Duplikate wirklich absolut ausgeschlossen.

hash=z7df89a87ds7f78sd98z7f
dateiname=img1.jpg

Datei wird als $hash gespeichert, wenns sein muss noch mit extension und der Name der Datei sowie der Hash werden zusammen in der DB hinterlegt zusammen mit Kommentar o.ä. und schon hat man auch etwas, das man durchsuchen kann.

Duplikate kommen nicht mehr vor.

Beim Kopieren, Verändern o.ä. gleiches Vorgehen.

Dein Problem mit deinem Regex ist ja, was machst du wenn jemand ne Datei hochläd die sich "IMG_1234_MEIN_TOLLES_BILD_5678_ICH_AAERGER_DEN_ENTWICKLER_9012_BILD.jpg" nennt?

Hier wieder fragen?

cu
 

Slashwalker

Winterbanana
Registriert
15.05.06
Beiträge
2.213
Hi,

boah was fürn hausgemachter Kram.

Ein User läd eine Datei hoch:

Es wird ein Hash erzeugt oder eine Zufallszahl mit md5 und dieser Wert wird als Dateiname auf der Platte genutzt:
Man könnte etwas über Datum,Uhrzeit plus ein paar bytes aus /dev/urandom nehmen, damit hat man Duplikate wirklich absolut ausgeschlossen.

hash=z7df89a87ds7f78sd98z7f
dateiname=img1.jpg

Datei wird als $hash gespeichert, wenns sein muss noch mit extension und der Name der Datei sowie der Hash werden zusammen in der DB hinterlegt zusammen mit Kommentar o.ä. und schon hat man auch etwas, das man durchsuchen kann.

Duplikate kommen nicht mehr vor.

Beim Kopieren, Verändern o.ä. gleiches Vorgehen.

Dein Problem mit deinem Regex ist ja, was machst du wenn jemand ne Datei hochläd die sich "IMG_1234_MEIN_TOLLES_BILD_5678_ICH_AAERGER_DEN_ENTWICKLER_9012_BILD.jpg" nennt?

Hier wieder fragen?

cu

Boah meinst du ich mach mir die Hose mit der Kneifzange zu?
Wenn ich einen Hash oder ähnliches nutzen dürfte, würde ich sicher kein so ein Aufriss machen. Aber es soll eben kein Hash sein. Und in eine DB wird da auch nix geschrieben.

Aber scheiß drauf, ich hab es auch ohne RegEx hinbekommen. Und der User kann seine Datei nennen wie er will, das bringt mich jetzt nicht mehr in Schwulitäten.
 

_linx_

Kleiner Weinapfel
Registriert
04.01.09
Beiträge
1.125
Sorry, aber mein Regex ist definitiv korrekt. Er liest dir genau den Tickcount und den originalen Dateinamen aus, was du mit diesen Informationen anstellst ist nicht mein Problem - aber du machst es garantiert falsch.
 

Slashwalker

Winterbanana
Registriert
15.05.06
Beiträge
2.213
Wie von Anfang an beschrieben war Ziel:
ersetze(dateiname,RegEx,"") Er sollte also _xl_copy_[tickcount] entfernen. Mittlerweile habe ich es ohne RegEx in mehreren Schritten gelöst.