2009-08-10 13 views
23

Po prostu mam głowę wokół wyrażeń regularnych i używam biblioteki Boost Regex.Jak uciec z ciągu znaków do wykorzystania w Boost Regex

Mam potrzebę użycia wyrażeń regularnych, które zawierają konkretny adres URL, i dławi się, ponieważ oczywiście w adresie URL znajdują się znaki zarezerwowane dla wyrażenia regularnego i muszą zostać zmienione.

Czy istnieje jakaś funkcja lub metoda w bibliotece Boost, aby uciec z ciągu znaków dla tego rodzaju użycia? Wiem, że są takie metody w większości innych implementacji regex, ale nie widzę jeden w Boost.

Czy istnieje lista wszystkich znaków, które powinny zostać usunięte?

Odpowiedz

32
.^$ | () [ ] { } * + ? \ 

Jak na ironię, można użyć wyrażenia regularnego, aby uciec z adresu URL, aby można go było wstawić do wyrażenia regularnego.

const boost::regex esc("[.^$|()\\[\\]{}*+?\\\\]"); 
const std::string rep("\\\\&"); 
std::string result = regex_replace(url_to_escape, esc, rep, 
            boost::match_default | boost::format_sed); 

(Flaga boost::format_sed określa użyć formatu wymiana ciąg SED. W sed ucieczką & wyjścia woli cokolwiek dopasowane całej wypowiedzi)

Lub jeśli nie są wygodne z sed Stringi zastępczej formatuj, po prostu zmień flagę na boost::format_perl i możesz użyć znanego $&, aby odnieść się do tego, co pasuje do całego wyrażenia.

const std::string rep("\\\\$&"); 
std::string result = regex_replace(url_to_escape, esc, rep, 
            boost::match_default | boost::format_perl); 
+0

Próbowałem użyć regex, aby to zrobić, ale nadal jestem dość niekompetentny i pojawiały się dziwne rzeczy: p Zamówiłem kilka książek na temat regexu dzisiaj, więc mam nadzieję, że moja ignorancja będzie krótkotrwała! W międzyczasie, dzięki regularnej zamianie ciągów znaków, aby uciec te postacie pracowały dla moich bezpośrednich potrzeb, dziękuję. – Gerald

+0

Dodałem kod do mojej odpowiedzi, która * myślę * powinna działać, aby dodać ukośnik odwrotny przed jakimkolwiek znakiem, który musi zostać zmieniony. Przez jakiś czas nie używałem doładowania, więc nie mam żadnych gwarancji. – Amber

+7

Było blisko, po prostu musiałem dodać "&" do końca rep i zadziałało. Dzięki. – Gerald

4

samo z boost::xpressive:

const boost::xpressive::sregex re_escape_text = boost::xpressive::sregex::compile("([\\^\\.\\$\\|\\(\\)\\[\\]\\*\\+\\?\\/\\\\])"); 

std::string regex_escape(std::string text){ 
    text = boost::xpressive::regex_replace(text, re_escape_text, std::string("\\$1")); 
    return text; 
} 
11

Korzystanie kod z Dav (+ poprawka z komentarzami), stworzyłem ASCII funkcji/Unicode regex_escape():

std::wstring regex_escape(const std::wstring& string_to_escape) { 
    static const boost::wregex re_boostRegexEscape(_T("[.^$|()\\[\\]{}*+?\\\\]")); 
    const std::wstring rep(_T("\\\\&")); 
    std::wstring result = regex_replace(string_to_escape, re_boostRegexEscape, rep, boost::match_default | boost::format_sed); 
    return result; 
} 

Dla ASCII wersji, użytkowania std::string/boost::regex zamiast std::wstring/boost::wregex.

Powiązane problemy