Narzędzia użytkownika

Narzędzia witryny


regex

Różnice

Różnice między wybraną wersją a wersją aktualną.

Odnośnik do tego porównania

Both sides previous revision Previous revision
regex [2008/04/17 00:19]
przemoc wersja prefinal
regex [2008/04/17 03:03] (aktualna)
przemoc wersja finalna
Linia 80: Linia 80:
   |                        | alternatywa   |                        | alternatywa
   [znaki^odrzuty] ​         | dopuszczalny znaki i niedopuszczalne odrzuty   [znaki^odrzuty] ​         | dopuszczalny znaki i niedopuszczalne odrzuty
 +  \<  \>   ​\b ​             | początek, koniec słowa i którekolwiek z nich
   \d  <​=> ​ [[:​digit:​]] ​    | cyfra   \d  <​=> ​ [[:​digit:​]] ​    | cyfra
   \l  <​=> ​ [[:​lower:​]] ​    | mała litera   \l  <​=> ​ [[:​lower:​]] ​    | mała litera
Linia 91: Linia 92:
   \W  <​=> ​ [^[:​word:​]] ​    | nie :znak "​słowny"​   \W  <​=> ​ [^[:​word:​]] ​    | nie :znak "​słowny"​
   (?#​komentarz) ​           | ignorowany (komentarz)   (?#​komentarz) ​           | ignorowany (komentarz)
-  (?:wzorzec) ​             | "​zjada"​ 0 znaków tylko jeżeli wzorzec się zgadza+  (?=wzorzec) ​             | "​zjada"​ 0 znaków tylko jeżeli wzorzec się zgadza
   (?​!wzorzec) ​             | "​zjada"​ 0 znaków tylko jeżeli wzorzec nie pasuje   (?​!wzorzec) ​             | "​zjada"​ 0 znaków tylko jeżeli wzorzec nie pasuje
  
Linia 107: Linia 108:
 #include <​boost/​regex.hpp>​ #include <​boost/​regex.hpp>​
 </​code>​ </​code>​
-Przy linkowaniu musimy natomiast dołączyć bibliotekę Boost.Regex,​ co w systemach *nixowych odbywa się za pomocą parametru '​-lboost_regex'​.+Przy linkowaniu musimy natomiast dołączyć bibliotekę Boost.Regex,​ co w systemach *nixowych odbywa się za pomocą parametru ​''​-lboost_regex''.
  
 Tak jak w przypadku innych bibliotek Boosta, wszystkie stałe, klasy i funkcje zewnętrzne znajdują się przestrzeni nazw ''​boost''​ i dla przejrzystości nie będę tego pisał przy przytaczaniu fragmentów definicji podstawowych elementów Boost.Regex. Tak jak w przypadku innych bibliotek Boosta, wszystkie stałe, klasy i funkcje zewnętrzne znajdują się przestrzeni nazw ''​boost''​ i dla przejrzystości nie będę tego pisał przy przytaczaniu fragmentów definicji podstawowych elementów Boost.Regex.
Linia 266: Linia 267:
     // Wyrażenie regularne zgodne z formatem IBAN     // Wyrażenie regularne zgodne z formatem IBAN
     // IBAN = International Bank Account Number     // IBAN = International Bank Account Number
-    static const boost::​regex ibanFormat("​[A-Z]{2}\\d{2} ?​[A-Z\\d]{4}( ?​\\d{4}){1,​} ?​\\d{1,​4}"​);​+    static const boost::​regex ibanFormat("​[A-Z]{2}\\d{2} ?​[A-Z\\d]{4}(?: ?​\\d{4}){1,​} ?​\\d{1,​4}"​);​
  
     // Sprawdź czy string ma format IBAN     // Sprawdź czy string ma format IBAN
Linia 308: Linia 309:
                   const basic_regex<​charT,​ traits>&​ e,                   const basic_regex<​charT,​ traits>&​ e,
                   match_flag_type flags = match_default);​                   match_flag_type flags = match_default);​
 +</​code>​
 +
 +Prosty przykład użycia korzystający również z iteratora po wszystkich dopasowaniach wyrażenia regularnego.
 +<code cpp>
 +#include <​iostream>​
 +#include <​string>​
 +#include <​boost/​regex.hpp>​
 +
 +// Callback dla funkcji std::​for_each operujący na wynikach dopasowania.
 +bool printRep(const boost::​smatch&​ what)
 +{
 +    std::cout << what[1] << " "; ​ // Wyświetl na standardowe wyjście pierwsze podwyrażenie.
 +    return true;                  // Nie zatrzymuj wykonywania pętli for_each.
 +}
 +
 +// Wczytaj linię z wejścia i sprawdź czy są w niej powtórzenia "​słów",​
 +// a jeżeli są, podaj jakie.
 +int main() {
 +    // Wyrażenie regularne reprezentujące powtarzające się słowa.
 +    boost::​regex rep("​(\\<​\\w+\\>​)(?:​\\s+\\<​\\1\\>​)+"​);​
 +    std::string line;
 +    std::​getline(std::​cin,​ line);
 +    // Początkowy iterator dopasowań do wyrażen regularnych.
 +    boost::​sregex_iterator begin(line.begin(),​ line.end(), rep);
 +    // Terminalny iterator dopasowań do wyrażen regularnych.
 +    boost::​sregex_iterator end;
 +    // Dla każdego dopasowania wywołaj funkcję printRep.
 +    std::​for_each(begin,​ end, &​printRep);​
 +    std::cout << std::endl;
 +    return 0;
 +}
 </​code>​ </​code>​
  
Linia 328: Linia 360:
                              const basic_string<​charT>&​ fmt,                              const basic_string<​charT>&​ fmt,
                              ​match_flag_type flags = match_default);​                              ​match_flag_type flags = match_default);​
 +</​code>​
 +
 +W domyślnej składni stringu formatującego (przy braku flagi ''​regex_constants:​literal''​) zdefiniowane są sekwencje specjalne odnoszące się do podmienianego dopasowania takie jak w Perlu (zaprezentowane zostały wcześniej w tabelce [[#​Dopasowania]]). Aby uzyskać na wyjściu znak dolara ($), trzeba napisać go dwukrotnie.
 +
 +Jako przykład zastosowania przedstawię kod aplikacji wyświetlającej na wyjście przekazany w 1. argumencie plik CSV (Comma-Separated Values) z zamienionymi miejscami pierwszymi dwiema kolumnami, a kolumny te są oddzielone przecinkiem.
 +<code cpp>
 +#include <​iostream>​
 +#include <​fstream>​
 +#include <​string>​
 +#include <​boost/​regex.hpp>​
 +
 +// Załaduj strumień wejściowy do stringa.
 +void loadFile(std::​string&​ s, std::​istream&​ is)
 +{
 +    s.erase();
 +    s.reserve(is.rdbuf()->​in_avail());​
 +    char c;
 +    while (is.get(c))
 +    {
 +        if (s.capacity() == s.size())
 +            s.reserve(s.capacity() * 3);
 +        s.append(1, c);
 +    }
 +}
 +
 +// Wyświetl plik CSV (o nazwie przekazanej w 1. argumencie) z zamienionymi pierwszymi 2 kolumnami
 +int main(int argc, const char** argv)
 +{
 +    // Wyrażenie regularne reprezentujące pierwsze dwie kolumny (druga może być pusta)
 +    boost::​regex re("​^([^,​\n]*),?​([^,​\n]*)"​);​
 +    // Format stringu odpowiadający podmienianemu dopasowaniu.
 +    std::string fmt("​\\2,​\\1"​);​
 +    try {
 +        std::​ifstream fs(argv[1]);​
 +        std::string in;
 +        loadFile(in,​ fs);
 +        // Wyświetl na wyjściu string in z zamienionymi dopasowaniami re na string formatujący fmt.
 +        std::cout << boost::​regex_replace(in,​ re, fmt);
 +    }
 +    catch(...) {
 +        return -1;
 +    }
 +    return 0;
 +}
 </​code>​ </​code>​
  
Linia 353: Linia 429:
 }; };
 </​code>​ </​code>​
 +
 +Po 2 przykłady użycia odsyłam na sam dół strony z dokumentacją [[http://​www.boost.org/​doc/​libs/​1_35_0/​libs/​regex/​doc/​html/​boost_regex/​ref/​regex_token_iterator.html|regex_token_iterator]].
  
 ===== Boost.Xpressive - relatywnie młody konkurent ===== ===== Boost.Xpressive - relatywnie młody konkurent =====
  
-Ważne innowacje:+Ważne innowacje ​w stosunku do Boost.Regex:
   * obsługa tworzenia (obok dynamicznych,​ podobnych w zapisie do Boost.Regex) statycznych wyrażeń regularnych,​ podobnych w zapisie do Boost.Spirit,​ przez przeciążanie operatorów i zastosowanie techniki zwanej szablonami wyrażeniowymi (ang. //​expression templates//​) - owa statyczność daje wiele możliwości,​ m.in. kontrolę poprawności takiego wyrażenia już w czasie kompilacji,   * obsługa tworzenia (obok dynamicznych,​ podobnych w zapisie do Boost.Regex) statycznych wyrażeń regularnych,​ podobnych w zapisie do Boost.Spirit,​ przez przeciążanie operatorów i zastosowanie techniki zwanej szablonami wyrażeniowymi (ang. //​expression templates//​) - owa statyczność daje wiele możliwości,​ m.in. kontrolę poprawności takiego wyrażenia już w czasie kompilacji,
   * możliwość mieszania statycznych i dynamicznych wyrażeń regularnych,​   * możliwość mieszania statycznych i dynamicznych wyrażeń regularnych,​
regex.txt · ostatnio zmienione: 2008/04/17 03:03 przez przemoc