Gå til innhold

case insensitive find()


Anbefalte innlegg

Driver her å roter med std::string variable. Og jeg har nå funnet ut at jeg kan finne ord og slikt med find(). Men det jeg har sliti litt med, som jeg har funnet ut av nå, er at den er case-sensitive, naturlignok. Så, er det noen måte å søke etter ting uten tanke på case?

 

Eventuelt, er det noen funksjon til å gjøre alle bokstaver i en streng om til lower/uppercase? Akkurat det trenger jeg uansett, så om noen vet det, hadde det også vært ok å finne ut :)

 

Cluet er at jeg prøver å putte sammen en hyperenkel htmlparser. Og da mener jeg hyperenkel. Den skal bare finne de 6-7 vanligste taggene, og plukke ut teksten av de. Problemet er at jeg vet jo ikke om folk har skrevet <tag>, <TAG>, <Tag>, <tAg>, <taG>, <TAg>, <TaG> eller <tAG>........

 

Eneste måten jeg kommer på for øyeblikket er å gå igjennom hele teksten bokstav for bokstav. Mulig det er sånn en er pent nødt til å gjøre det? men om det finnes ferdige funksjoner i std til dette, så hadde jo det vært litt ok, hehe.

 

Å skulle søke etter alle mulige kombinasjoner for alle taggene blir i alle fall håpløst. Det er helt sikkert :no:

 

noen som vet?

 

*savne php*

Endret av Tussi_qwerty
Lenke til kommentar
Videoannonse
Annonse
men til slike ting bruker man som regel ordentlige biblioteker:

http://www.boost.org/libs/regex/doc/index.html

5902319[/snapback]

 

Eller et skikkelig parserbibliotek også fra Boost: http://boost.org/libs/spirit/

 

 

Når det gjelder en case insensitive find kan du lage en traits-klasse til std::basic_string. Dette har både fordeler og ulemper. Men du kan få den til å se bort fra store og små bokstaver ved sammenligninger.

 

Her er et eksempel hentet fra fra mitt strengbibliotek:

 

#include <iostream>
#include <string>
#include <cassert>

namespace stdext
{

 namespace detail
 {
   inline char ToUpper(char ch_)
   {
     return static_cast<char>( ::toupper(ch_) );
   }

   inline wchar_t ToUpper(wchar_t ch_)
   {
     return ::towupper(ch_);
   }
 }



 template <typename CharType>
 inline int CompareNoCase(const CharType* left_, const CharType* right_, size_t count_)
 {
   assert(left_ && right_);

   int res = 0;

   for(size_t i=0; i<count_; i++)
   {
     CharType l = detail::ToUpper( *left_++ );
     CharType r = detail::ToUpper( *right_++ );

     if(l != r)
     {
       l < r ? res = -1 : res = 1;
       break;
     }
   }

   return res;
 }



 template <typename CharType>
 struct ci_char_traits : public std::char_traits<CharType> 
 {
   static bool eq( CharType c1, CharType c2 )
   {
     return (detail::ToUpper(c1) == detail::ToUpper(c2));
   }

   static bool lt( CharType c1, CharType c2 )
   {
     return ((CompareNoCase(&c1, &c2, 1) < 0) ? true : false);
   }

   static int compare( const CharType* s1, const CharType* s2, size_t n )
   {
     return CompareNoCase(s1, s2, n);
   }

   static const CharType* find( const CharType* str_, size_t num_, CharType ch_ )
   {
     while( num_ > 0 && detail::ToUpper(*str_) != detail::ToUpper(ch_) )
     {
       --num_;
       ++str_;
     }

     return num_ > 0 ? str_ : 0;
   }
 };
}



int main()
{
 typedef std::basic_string<char, stdext::ci_char_traits<char> > istring;

 istring str("aBc");

 if(str == "ABC")
   std::cout << "aBc equals ABC..." << std::endl;

}

 

Koden kan se litt skremmende ut for et utrent øye, men den er egentlig ikke veldig komplisert. Selve magien skjer i ci_char_traits. Resten er kun hjelpefunksjoner.

 

Å bruke std::basic_string på denne måten lager en del begrensinger hvis du ikke implementerer en del spesialiseringer mot f.eks. streambibliotekene. Du kan heller ikke sammenligne de med f.eks. std::string (av naturlige årsaker). Men du kan som i eksemplet over sammenligne med vanlige c-strenger (og dermed std::string via c_str()-metoden).

Lenke til kommentar

litt flaut å ikke ha funnet tolower og toupper funksjonene da...tror jeg er litt for vandt til java sitt velorganiserte system. leter bare i string-funksjonene og rundt der. tenker ikke på at de finnes spredt rundt over det hele, hehe.

 

når det gjelder disse bibliotekene, så er vel det noe en kunne gått for om dette var et prosjekt av noe slag. men nå er dette en skoleoppgave, og jeg føler at jo mer jeg lager fra bunnen av, jo mere lærer jeg. dette streng-behandlings styret er i alle fall noe jeg definitivt trenge rå bli tryggere på... kan man si :p

 

men takk for gode råd! får se hva jeg gjør. nå har jeg i alle fall noe å komme meg videre med :D

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...