Emails aus textdateien parsen



  • Hallo alle miteinander,

    Ich schreibe gerade eine Anwendung die aus textbergen die im büro angefallen sind(txt-dateien) die emailadressen unserer Kunden herausfischt. Ich habe die dateien(ursprünglich ~2mb/datei) in kleine schnipsel zerkleinert, welche ich jetzt gerne parsen würde. Das problem ist, wie kann ich in C++ regex verwenden? oder geht das auch anders?

    Ich weiss nicht wie ich den parser bauen muss, damit er auch schnell und zuverlässig funktioniert.

    Wäre super wenn mir jemand einen Tip oder kleinen codeschnipsel geben könnte,

    danke,

    Pascal



  • Beim BCB wird eine PCRE-Unterstützung mitgeliefert (siehe Hilfe -> Suchen), allerdings relativ spärlich dokumentiert.

    Ansonsten kannst du einen Parser z.b. mit den Methoden von AnsiString basteln, das Filtern von E-Mail-Adressen ist ja nicht sooo komplex.



  • hi,

    ich kenne oder verwende regex als komponente von systools. da hab ich da so gemacht:

    - zu erst lege ich eine string liste an

    const String ExlList[] = {"NULL",
    "den text will ich net sehen"
    };
    const int SizeExlList = sizeof(ExlList)/sizeof(ExlList[0]);

    - dann überprüfen (bool function als privat in der h deklariert)

    bool TForm1::IsInExlList(String wert)
    {
    TMatchPosition hlp;
    for (int i = 0; i < SizeExlList; i++)
    {
    RegExp->MatchPattern->Clear();
    RegExp->MatchPattern->Add(ExlList[i]);
    if (RegExp->CheckString(wert,hlp)) return true;
    }
    return false;
    }

    - und nü die anzeige der Daten

    void __fastcall TForm1::FormShow(TObject *Sender)
    {
    while (!Datei->Eof){
    if (!IsInExlList(hier der ausgelesene String rein)){
    //dann mache etwas
    } else{
    sonst nischt
    }

    Ob dir das was hilft weiss ich nicht aber so hab ich es gemacht.



  • Hi!

    Schau mal auf meiner Seite unter BC++Builder->Parser!

    F98



  • Habe mir die Sourcen angeschaut, aber wie kann ich da die tokens so ändern dass ich emails angezeigt bekomme?

    habe es geschafft die @s zu parsen, habe aber probleme mit exceptions die auftreten weil sie ir sagen dass die Zeilen zu lange sind, wie kann och denn da den Buffer hochstellen oder ähnlches?

    gruß und danke



  • Wieso schreibst Du das nicht selber ? Such im Text nach dem Knuddel (@), ab deiser Position nach links bis zum Auftreten eines Leerzeichens, jetzt hast Du den Anfang der E-Mail Addi. Dann vom Knuddel aus nach rechts bis zum nächsten Leerzeichen, jetzt hast du das Ende der Addi ... usw.



  • donpasquale schrieb:

    Habe mir die Sourcen angeschaut, aber wie kann ich da die tokens so ändern dass ich emails angezeigt bekomme?

    Die Tokens kannst Du nicht ändern, die sind ja fest im Eingabetext. Der Parser gibt Dir nur das akt. Zeichen und den dazu ermittelten Typ zurück (toSymbol, toInteger, toFloat, toString), was Du damit anstellst ist Deine Sache. 😉

    Du könntest wie folgt vorgehen:

    1. immer den voherigen TokenTyp + das vorherige Token merken
    2. wenn Du auf ein Schlüsselzeichen triffst ("@"), dann eine spez. Aktion einleiten, sprich das vorherige Token mit einbeziehen und eine Aussage treffen
    3. bis toEOF weiter parsen

    Edit:
    Zitate bitte auf das Notwendigste beschränken. Danke!



  • Hi,

    hänge mal wieder fest und komme nicht weiter, habe das Problem das ich nicht weiss wie ich einen TFileStream auf eine bestimmte Zeile an eine bestimmte Position setzen kann.

    Wäre super wenn mir das kurz jemand sagen könnte.

    danke

    ps: der Rest hat jetzt super geklappt mit dem Parser. 🙂



  • donpasquale schrieb:

    TFileStream auf eine bestimmte Zeile an eine bestimmte Position setzen

    Schon mal einen Blick auf die Methoden von TFileStream geworfen? 😉

    Und in Zukunft bitte die Faustregel beachten: ein Thema pro Thread, ein Thread pro Thema.



  • Hallo nochmal alle zusamman,

    Ich habe den Emailparser soweit hinbekommen, ausser dass ich immer am ende der emails häßliche Zeichen bekomme.

    Ich müsste eigentlich nur wissen wie man sauber einen String nach Zeichen durchforschen kann und wie man Sonderzeichen ganz unterbinden kann(ausser @ . und -).

    Ich habe in dem Parse einfach die @s lokalisiert und die position in abhängigkeit zu der file abgespeichert.

    ich steppe mit TFileStream::Seek durch die File bis ein begrenzerzeichen kommt. doch das weiss ich eben nicht wie man das sauber macht.

    danke im Voraus,

    Pascal

    ps, jansen, danke schonmal für deine Antworten 🙂



  • Zeig doch mal den Code, damit man mal nachvollziehen kann was du eigentlich machst.



  • Den Parser mit dem Parserobjekt habe ich fertig, der schreibt jedes @ in eine PositionList und den Dateinamen dazu auch gleich.

    dann wird die Phase2 des Parsers aufgerufen:

    hier der code:

    void parserPhase2()
    {
    AnsiString tempContt="";
    int startPos=0;
    if (Form1->EmailPositionList->Items->Count == Form1->EmailZeilenList->Items->Count)
    {
    for (int i=0; i < Form1->EmailFileList->Items->Count; i++)
                    {
                    try{
                    TFileStream *F = new TFileStream(Form1->EmailFileList->Items->operator [](i), fmOpenRead);
                    char * buff1 = new char[61];
                    F->Seek(Form1->EmailPositionList->Items->operator [](i).ToInt(),soFromBeginning);
                    F->Read(buff1, 1);
                    int ofs=0;
                    startPos=F->Position;
                    while(buff1[0]!='"'&&buff1[0]!=' '&&buff1[0]!=':'&&buff1[0]!='<'&&buff1[0]!='>'&&buff1[0]!='?'&&buff1[0]!='/'&&buff1[0]!='\\'&&buff1[0]!='!'&&buff1[0]!='-')
                            {
                            if (startPos>0)
                                    {
                                    ofs++;
                                    F->Seek(((Form1->EmailPositionList->Items->operator [](i).ToInt())-ofs),soFromBeginning);
                                    buff1="";
                                    F->Read(buff1, 1);
                                    Application->ProcessMessages();
                                    startPos=F->Position;
                                    }
                            else
                                    {
                                    ShowMessage("Nothing found: " + (AnsiString)buff1[0] + " / offset: "+(AnsiString)startPos);
                                    }
                            }
                            Form1->EmailBeginningList->Items->Add(startPos);
                            F->Free();
                    }
                    catch(...)
                    {}
                   }
    
    for (int i=0; i < Form1->EmailFileList->Items->Count; i++)
                    {
                    startPos=0;
                    tempContt="";
                    char * buff1 = new char[100];
                    buff1="";
                    try{
                    TFileStream *F = new TFileStream(Form1->EmailFileList->Items->operator [](i), fmOpenRead);
    
                            int ofs=0;
                            F->Seek(Form1->EmailPositionList->Items->operator [](i).ToInt(),soFromBeginning);
                            F->Read(buff1, 1);
                            startPos=F->Position;
                            while(buff1[0]!='"'&&buff1[0]!=' '&&buff1[0]!=':'&&buff1[0]!='<'&&buff1[0]!='>'&&buff1[0]!='?'&&buff1[0]!='/'&&buff1[0]!='\\'&&buff1[0]!='!'&&buff1[0]!='-')
                            {
                            if (startPos>0)
                                    {
                                    ofs++;
                                    F->Seek(((Form1->EmailPositionList->Items->operator [](i).ToInt())+ofs),soFromBeginning);
                                    buff1="";
                                    F->Read(buff1, 1);
                                    Application->ProcessMessages();
                                    startPos=F->Position;
                                    }
                            else
                                    {
                                    ShowMessage("Nothing found: " + (AnsiString)buff1[0] + " / offset: "+(AnsiString)startPos);
                                    }
                            }
                            Form1->EmailEndList->Items->Add(startPos);
                            Form1->emailFertigFileList->Items->Add(Form1->EmailFileList->Items->operator [](i));
    
                            F->Free();
                    }
                    catch(...)
                    {}
                    }
            }
    }
    


  • ich weiss dass der code nicht sonderlich gut ist, aber könnte sich bitte einer erbarmen und mir die fehler rausmachen? wäre super. Oder wenigstens ein paar tips.

    danke

    Pascal


Anmelden zum Antworten