schnelles Regex-Cleaning



  • Jo, weiß das in C++ auch altes C funzt, dachte nur es gäbe etwas kürzeres... irgendwas schon vorgeschrieben... will nicht immer das Rad neu erfinden und meine eigenen Fehler suchen gehen.. 😃



  • Ich würds wahrscheinlich so in etwa anstellen:

    #include <cstdlib>
    using std::size_t;
    
    template <typename T>
    class CountEvil
    {
    public:
     typedef size_t size_type;
     typedef T value_type;
    
    private:
     T lower;
     T upper;
    
     size_type count; 
    public:
     CountEvil(T _lower, T _upper) : lower(_lower), upper(_upper), count(0) {}
     void operator () (T val) {if ((val > upper) || (val < lower)) ++count;}
    
     size_type Get() const {return count;}
    };
    
    #include <algorithm>
    #include <string>
    #include <iostream>
    
    int main()
    {
     std::string in;
     std::getline (std::cin, in);
    
     CountEvil <std::string::value_type> evilchars('a', 'Z');
    
     std::for_each(in.begin(), in.end(), evilchars);
    
     std::cout << evilchars.Get() << std::endl;
    }
    

    bb


  • Administrator

    @unskilled,
    Dein Programm funktioniert nicht. An std::for_each wird eine Kopie übergeben 😉

    Für Regex gibt es:
    http://www.boost.org/doc/libs/1_38_0/libs/regex/doc/html/index.html
    http://www.boost.org/doc/libs/1_38_0/doc/html/xpressive.html

    Aber hier empfiehlt es sich den genau gleichen Weg einzuschlagen, wie in C auch, dürfte wohl das schnellste und einfchste sein. Ich würde aber nicht std::for_each nehmen, sondern zum zählen z.B. std::count_if :
    http://www.cplusplus.com/reference/algorithm/count_if/

    Oder zum löschen, std::remove_if :
    http://www.cplusplus.com/reference/algorithm/remove_if/

    Grüssli



  • Dravere schrieb:

    Oder zum löschen, std::remove_if :
    http://www.cplusplus.com/reference/algorithm/remove_if/

    ACK 🙂



  • japp, count_if wär auch ne idee gewesen - verdammt 😉

    btw:

    int main()
    {
     std::string in;
     std::getline (std::cin, in);
    
     const CountEvil <std::string::value_type> evilchars = std::for_each(in.begin(), in.end(), CountEvil <std::string::value_type> ('a', 'Z'));
    
     std::cout << evilchars.Get() << std::endl;
    }
    


  • Bei std::remove_if() sollte man noch beachten, dass zuerst mal nichts gelöscht, sondern nur die Iterator-Range so umgeordnet wird, dass man einen zusammenhängenden Bereich am Schluss der Range mittels erase() wirklich löschen kann.



  • Ich würds wahrscheinlich so in etwa anstellen:

    #include <cstdlib>
    using std::size_t;

    template <typename T>
    class CountEvil
    {
    public:
    typedef size_t size_type;
    typedef T value_type;

    private:
    T lower;
    T upper;

    size_type count;
    public:
    CountEvil(T _lower, T _upper) : lower(_lower), upper(_upper), count(0) {}
    void operator () (T val) {if ((val > upper) || (val < lower)) ++count;}

    size_type Get() const {return count;}
    };

    #include <algorithm>
    #include <string>
    #include <iostream>

    int main()
    {
    std::string in;
    std::getline (std::cin, in);

    CountEvil std::string::value_type evilchars('a', 'Z');

    std::for_each(in.begin(), in.end(), evilchars);

    std::cout << evilchars.Get() << std::endl;
    }

    oder einfach

    #include <string> 
    #include <iostream> 
    using namespace std;
    int main() 
    { 
     std::string in; 
     std::getline (std::cin, in); 
    
     int count=0;
     for(string::iterator i=in.begin();i!=in.end();++i)
       if('a'<=*i && *i<='z')
         ++count;
     cout << count << '\n'; 
    }
    


  • volkard schrieb:

    Ich würds wahrscheinlich so in etwa anstellen:

    #include <cstdlib>
    using std::size_t;

    template <typename T>
    class CountEvil
    {
    public:
    typedef size_t size_type;
    typedef T value_type;

    private:
    T lower;
    T upper;

    size_type count;
    public:
    CountEvil(T _lower, T _upper) : lower(_lower), upper(_upper), count(0) {}
    void operator () (T val) {if ((val > upper) || (val < lower)) ++count;}

    size_type Get() const {return count;}
    };

    #include <algorithm>
    #include <string>
    #include <iostream>

    int main()
    {
    std::string in;
    std::getline (std::cin, in);

    CountEvil std::string::value_type evilchars('a', 'Z');

    std::for_each(in.begin(), in.end(), evilchars);

    std::cout << evilchars.Get() << std::endl;
    }

    oder einfach

    #include <string> 
    #include <iostream> 
    using namespace std;
    int main() 
    { 
     std::string in; 
     std::getline (std::cin, in); 
    
     int count=0;
     for(string::iterator i=in.begin();i!=in.end();++i)
       if('a'<=*i && *i<='z')
         ++count;
     cout << count << '\n'; 
    }
    

    Gott! 👍



  • Danke für alle eure Beiträge.. habe mir das hier zusammen geschrieben....

    int F_Clean(string& str_in)
    {
        string str_temp;
        int int_now, int_count, int_re = 0;
        char chr_t;
        str_temp.clear();
        for (int_count = 0; int_count < str_in.size() ; int_count++)
        {
            int_now = str_in[int_count];
            if ((int_now > 31) && (int_now < 127))
            {
                chr_t = int_now;
                str_temp=str_temp + chr_t;
            }
            else
            {
                int_re++;
            }
        }
        str_in = str_temp;
        return int_re;
    }
    

    Nicht schön aber es funzt 🕶

    BEDANKT!!!!!!!!!!!



  • ein paar ideen, die mir da einfallen

    int F_Clean(string& str_in)
    {
        string str_temp;
        for (string::itearator i=str_in.begin();i!=str.end();++i)
            if ((*i > 31)/* && (*i < 127)*/)//signed char?!
                str_temp+=*i;
        swap(str_in,str_temp);
        return str_tmp.size()-str_in.size();
    }
    

    /*remove_if tönt sehr lecker, das würde ich aber vertahen bis lamda-dinge da sind. ;)*/


Anmelden zum Antworten