[php] patroon herkenning

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Spider.007
  • Registratie: December 2000
  • Niet online

Spider.007

* Tetragrammaton

Topicstarter
Nee, dit is geen vraag die simpel op te lossen is met een regexp (hoop ik :X) Maargoed; ik heb een grote verzameling bestanden (+/- 10.000) met namen waar een patroon inzit. Zo hebben we bijvoorbeeld:




• blablabla_026.jpg
• blablabla_027.jpg
• blablabla_028.jpg




• b135.jpg
• b136.jpg
• b137.jpg




• 103-0331_IMGa.jpg
• 103-0332_IMGa.jpg
• 103-0332_IMGa.jpg




Nu is het redelijk eenvoudig hier een patroon in te herkennen :) Maar hoe zetten we dat om in programma code? Vaak gaat het om een getal dat opgehoogd wordt; maar ik kan geen manier bedenken om een programma hierop los te laten. Even voor de duidelijkeheid; de bedoeling is dat alles uiteindelijk in een eigen map terecht komt.

Het idee wat ik iig zelf heb is twee strings vergelijken en dan moet het aantal overeenkomende characters meer dan 70% oid. Ik weet echter niet of dit optimaal is.

Ik heb gegoogled; en gezocht op GoT; maar beiden brachten mij weinig soelaas. Hebben jullie tips over hoe dit aan te pakken? Is er toch een simpele regexp die ik over het hoofd zie?

---
Prozium - The great nepenthe. Opiate of our masses. Glue of our great society. Salve and salvation, it has delivered us from pathos, from sorrow, the deepest chasms of melancholy and hate


Acties:
  • 0 Henk 'm!

  • -Tibo-
  • Registratie: Januari 2002
  • Niet online

-Tibo-

ow = teh

Je kan voor alle filenames alle integers eruit halen met een regexp, vervolgens de ints van de verschillende files met elkaar vergelijken of ze opvolgend zijn. Je kan dan ook nog tjekken op welke charpositie van de filename die int zit om te dubbelchecken of het wel de juiste match is.

Dat zou ik proberen iig :)

Acties:
  • 0 Henk 'm!

  • Spider.007
  • Registratie: December 2000
  • Niet online

Spider.007

* Tetragrammaton

Topicstarter
Klinkt als een goed idee. Maar wat gebeurt er bij patronen als:

• 234a.jpg
• 234b.jpg
• 234c.jpg

:? Uiteraardt wil ik een zo generiek mogelijk manier bedenken om een patroon te herkennen; en deze zou door jouw zoektocht naar ints ertussendoor vallen.

Nogmaals; het idee is voldoende voor mijn probleem; maar is niet generiek genoeg :)

---
Prozium - The great nepenthe. Opiate of our masses. Glue of our great society. Salve and salvation, it has delivered us from pathos, from sorrow, the deepest chasms of melancholy and hate


Acties:
  • 0 Henk 'm!

  • ANdrode
  • Registratie: Februari 2003
  • Niet online
kan je niet per uniek voorstukje alles in een aparte map pleuren? zoja:
regexp die stuk voor verandering van letter->cijfer of omgekeerd geeft (denk ook aan -'jes), en je bent er al bijna.

Alleen die directory B wordt wat vervelender :p

Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Ik zou het als volgt doen:

* Vul een string/array met een aantal "-" tekens, even lang als het bestand
* Pak een filenaam(a) en een volgende filenaam(b). Markeer alle tekens die verschillend zijn tussen a en b, in je array of string
* Pak nog een filenaam(c) en markeer nogmaals alle gewijzigde (a-c en/of a-b) tekens.
* Doe dit totdat je een flink aantal (random?) bestanden hebt gehad.
* Je hebt dan bijvoorbeeld voor "103-0331-IMGa.jpg" en "103-0332-IMGa.jpg" de volgende waarde "ontdekt": "-------x---------". Je kunt dit beschouwen als een "mask".

Je kunt nu op de plek van de minnetjes de originele "letters" terugzetten en de "x"-jes laten lopen van 0 tot 9 ofzo...Je kunt m.b.v. je mask kijken wat het verschil is tussen twee opeenvolgende bestanden ofzo, en daaruit afleiden of je met ints/chars of whatever te maken hebt.

<dit is heel simpel uitgelegd, er zijn veel mooiere methodes om patronen te herkennen, maar deze methode zal wel voldoen>

[ Voor 36% gewijzigd door RobIII op 08-04-2003 22:58 . Reden: effe wat uitgebreid :P ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • Eegee
  • Registratie: Januari 2000
  • Laatst online: 17:48
Als je de ASCII waarden van alle letters nou eens bij elkaar AND en dan kijken welke er gelijk zijn en welke verschillend ? Wat RobIII ook zegt eigenlijk.

[ Voor 12% gewijzigd door Eegee op 08-04-2003 22:56 ]


Acties:
  • 0 Henk 'm!

  • Spider.007
  • Registratie: December 2000
  • Niet online

Spider.007

* Tetragrammaton

Topicstarter
ANdrode schreef op 08 April 2003 @ 22:52:
kan je niet per uniek voorstukje alles in een aparte map pleuren? zoja:
regexp die stuk voor verandering van letter->cijfer of omgekeerd geeft (denk ook aan -'jes), en je bent er al bijna.

Alleen die directory B wordt wat vervelender :p
Nog een leuk voorbeeld dan:

• 1blaat1.jpg
• 1blaat2.jpg
• 1blaat3.jpg
• 2blaat1.jpg
• 2blaat2.jpg
• 2blaat3.jpg
• 3blaat1.jpg
enz.

Hier zit een blaat patroon in; maar zou op jouw manier een groot aantal directories op leveren.

[ Voor 42% gewijzigd door Spider.007 op 08-04-2003 22:56 ]

---
Prozium - The great nepenthe. Opiate of our masses. Glue of our great society. Salve and salvation, it has delivered us from pathos, from sorrow, the deepest chasms of melancholy and hate


Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Spider.007 schreef op 08 april 2003 @ 22:56:
[...]
Nog een leuk voorbeeld dan:
<knip>
Je maakt het wel steeds gekker ;)

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • Spider.007
  • Registratie: December 2000
  • Niet online

Spider.007

* Tetragrammaton

Topicstarter
Dat idee van het mask in inderdaad heel interessant. Alleen gaat het hier om 10.000 bestanden welke niet allemaal binnen een patroon zijn te vangen (ik ga ervanuit dat 80% dat wel is) Dat betekent dat er 10.000 ^ weetikveelhoeveelmasks aan vergelijkingen moeten worden gedaan. Wellicht is de methode die jij aandraagt inderdaad een veelgebruikte, goede oplossing; maar zie ik iets verkeerd?
RobIII schreef op 08 april 2003 @ 22:58:
[...]

Je maakt het wel steeds gekker ;)
We doen ons best >:)

...om een zo generiek mogelijk patroonherkenner te maken uiteraardt O-)

[ Voor 20% gewijzigd door Spider.007 op 08-04-2003 23:01 ]

---
Prozium - The great nepenthe. Opiate of our masses. Glue of our great society. Salve and salvation, it has delivered us from pathos, from sorrow, the deepest chasms of melancholy and hate


Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Nee, je begrijpt me niet helemaal.
Je gaat maar 1 mask maken:



Init: Mask = "-----------------"

Stap 1:

bestand a: 103-0331_IMGa.jpg
bestand b: 103-0332_IMGa.jpg

mask is nu "-------X---------"

Stap 2:

bestand b: 103-0332_IMGa.jpg
bestand c: 103-0333_IMGa.jpg

mask is nu "-------X---------" (nog steeds)

stap 3:

bestand c: 103-0333_IMGa.jpg
bestand d: 203-0331_IMGa.jpg

mask is nu "X------X---------"

stap 4:

bestand d: 203-0331_IMGa.jpg
bestand e: 204-1233_IMGa.jpg

mask is nu "X-X-XXXX---------"

stap 5:

bestand e: 203-0331_IMGa.jpg
bestand f: 204-1233_IMGb.jpg

mask is nu "X-X-XXXX----X----"



Als er een bepaald percentage X-en in je mask staat is je "pattroon" te vaag en kun je kappen. Maar is na alle bestanden je mask nog steeds b.v. "X------X---------" dan kun je vervolgens gaan kijken (m.b.v. ASCII codes bijvoorbeeld) "hoeveel verschil" er tussen 2 bestanden zit...

bestand c: 103-0333_IMGa.jpg
bestand d: 203-0338_IMGa.jpg

Het verschil op positie 1 is 1, dus kun je die steeds met 1 ophogen. Het verschil op positie 8 is 5, dus die moet je dan telkens met 5 ophogen???

Maar nogmaals: Dit is ZEKER NIET fool-proof en niet dé methode... Je kunt nog wel wat extra intelligentie inbouwen door te checken op letters/cijfers e.d maar ach... :P

Je moet overigens wel eerst effe je bestanden sorteren op naam dan ;)

/edit/
Heel effe snel snel wat VB code in mekaar geflanst (Proof of Concept, is niet voor [rml][ alg] fraaiste prog voorbeelden.[/rml] bedoeld :P, eerder [rml][ alg] slechtste prog voorbeelden.[/rml] B: )
Visual Basic:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
Option Explicit

Private Function GetMask(sDir As String, Optional sExtension As String = ".*") As String
    Dim sTMPFile(1, 1)
    Dim sMask As String
    Dim lTMP As Long
    
    sDir = Trim(sDir)
    sDir = IIf(Right(sDir, 1) <> "\", sDir & "\", sDir)
    
    sTMPFile(1, 0) = Dir(sDir & "*" & sExtension)
    sTMPFile(1, 1) = Len(sTMPFile(1, 0))
    If sTMPFile(1, 1) > 0 Then
        sMask = String(sTMPFile(1, 1), "-")
        While sTMPFile(1, 1) > 0
            sTMPFile(0, 0) = sTMPFile(1, 0)
            sTMPFile(0, 1) = sTMPFile(1, 1)
            sTMPFile(1, 0) = Dir
            sTMPFile(1, 1) = Len(sTMPFile(1, 0))
            If sTMPFile(1, 1) > Len(sMask) Then sMask = sMask & String(sTMPFile(1, 1) - Len(sMask), "X")
            For lTMP = 1 To IIf(sTMPFile(1, 1) < sTMPFile(0, 1), sTMPFile(1, 1), sTMPFile(0, 1))
                If Mid(sTMPFile(0, 0), lTMP, 1) <> Mid(sTMPFile(1, 0), lTMP, 1) Then Mid(sMask, lTMP, 1) = "X"
            Next
        Wend
    End If
    GetMask = sMask
End Function

Private Function MaskDiff(sMask As String) As Double
    MaskDiff = (Len(Replace(sMask, "-", "")) / Len(sMask)) * 100
End Function

Private Sub Form_Load()
    Dim sTestMask As String
    
    sTestMask = GetMask("C:\test")
    Debug.Print sTestMask
    Debug.Print "Difficulty pattern: " & FormatNumber(MaskDiff(sTestMask), 2) & " of 100"
End Sub


Laat deze code maar eens los op zo'n directory. Of op "C:\Windows" as a matter of fact. Dit kan mooier/sneller/optimaler en whatever, het gaat om het idee.

Helaas heb ik niks bij de hand om het effe in PHP bij mekaar te gooien en testen dus...

[ Voor 92% gewijzigd door RobIII op 08-04-2003 23:47 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • Limhes
  • Registratie: Oktober 2001
  • Laatst online: 08:38
Je kan ook ipv een mask met Levenstein werken. Deze methode berekent het aantal karakters dat je moet inserten/deleten/vervangen om op de andere te komen. Dus:
PHP:
1
2
3
4
5
6
7
8
9
<?
foreach ($list as $line) // of hoe je ook door je lijst fietst...
{
  if (levenstein($line, $previous_line) < 2) // of meer/minder als je dat wilt
    // hoort bij zelfde serie
  else
    // hoort niet bij zelfde serie
}
?>

Acties:
  • 0 Henk 'm!

  • Spider.007
  • Registratie: December 2000
  • Niet online

Spider.007

* Tetragrammaton

Topicstarter
Bedankt allemaal; ik laat binnenkort horen hoe ik het uiteindelijk heb opgelost. Bedankt voor de uitgebreide documentatie en uitlleg RobIII :)

---
Prozium - The great nepenthe. Opiate of our masses. Glue of our great society. Salve and salvation, it has delivered us from pathos, from sorrow, the deepest chasms of melancholy and hate


Acties:
  • 0 Henk 'm!

  • Spider.007
  • Registratie: December 2000
  • Niet online

Spider.007

* Tetragrammaton

Topicstarter
Tada:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
<html>
    <head>
        <title>Spider.007's photoSort</title>
    </head>
    <body>
    <pre>
<hr>
Hi there,

Welcome to photoSort!
<?PHP
$photoDirectory =   '/tmp/photos';
$rawFileList =      array();
$trimmedFileList =  array();

echo "We are now populating the files in $photoDirectory.";
$rawFileList = getFiles($photoDirectory);
echo "\n\tDone; found ".count($rawFileList)." files in there.\n";

echo "Let's strip off all non text from the filenames and search for catagories.";
foreach ($rawFileList as $rawFileListItem){
    $theItem = str_replace(".jpg", "", $rawFileListItem);
    $theTrimmedItem = preg_replace("/(\W|\d|_)/", "", $theItem);
    
    if (strlen($theTrimmedItem) > 2 ) $trimmedFileList[$theTrimmedItem][] = $rawFileListItem;
}
echo "\n\tDone; removed all digits, non-word characters and underscores from the filenames and created ".count($trimmedFileList)." catagories";

echo "\nLet's get rid of all catagories < 10 items";
foreach ($trimmedFileList as $trimmedFileListItem => $fileNamesArray) if (count($fileNamesArray) < 10) unset($trimmedFileList[$trimmedFileListItem]);
echo "\n\tDone, there are now ".count($trimmedFileList)." catagories";

echo "<br><hr>";
foreach ($trimmedFileList as $trimmedFileListItem => $fileNamesArray){
    echo "\n<b>$trimmedFileListItem</b> contains <b>".count($fileNamesArray)."</b> files.";
    foreach ($fileNamesArray as $fileNamesArrayItem) moveFile($photoDirectory."/".$fileNamesArrayItem, $photoDirectory."/".$trimmedFileListItem);
}
echo "<br><hr>";

// Move a file to a specified catagory and create directory if necessary
function moveFile($fileName, $destinationDirectory){
    if (!is_dir($destinationDirectory)) exec("mkdir $destinationDirectory");
    exec("mv ".$fileName." ".$destinationDirectory."/");
    echo "\n\tMoved $fileName to $destinationDirectory";
}

// Populate all files in the given directory and return them in an Array
function getFiles($theDirectory){
    $fileNames = array();
    $dirHandle = opendir($theDirectory);

    while ($dirName = readdir($dirHandle))
        if (!is_dir($theDirectory.$dirName) && $dirName != "." && $dirName != "..") $fileNames[] = $dirName;

    closedir($dirHandle);
    sort($fileNames);
    return $fileNames;
}
?>
    </pre>
    </body>
</html>

:)

---
Prozium - The great nepenthe. Opiate of our masses. Glue of our great society. Salve and salvation, it has delivered us from pathos, from sorrow, the deepest chasms of melancholy and hate

Pagina: 1