2012-12-20 3 views
2

C++ Windows 프로젝트 (Visual Studio 2010)에서 std::regex_replace을 사용하고 있습니다. 내가 result"https://www.wikipedia.org/" 것으로 기대std :: regex_replace가 예기치 않은 결과를 나타냄

std::string str("http://www.wikipedia.org/"); 
std::regex fromRegex("http://([^@:/]+\\.)?wik(ipedia|imedia)\\.org/", std::regex_constants::icase); 
std::string fmt("https://$1wik$2.org/"); 
std::string result = std::regex_replace(str, fromRegex, fmt); 

,하지만 난 "https://www.wikipedia.wikipedia.org/"을 얻을 : 코드는 다음과 같습니다.

sed와 빠른 검사가 나에게 예상 된 결과

$ cat > test.txt 
http://www.wikipedia.org/ 
$ sed 's/http:\/\/([^@:\/]+\.)?wik(ipedia|imedia)\.org\//https:\/\/$1wik$2.org\//' test.txt 
http://www.wikipedia.org/ 

차이가 어디에서 오는지 내가하지 않습니다를 제공합니다. std::regex_replace과 함께 사용할 수있는 플래그를 확인했는데,이 경우에 도움이되는 플래그를 보지 못했습니다.

업데이트

이 변종은 잘 작동 :

std::regex fromRegex("http://([^@:/]+\\.)wik(ipedia|imedia)\\.org/", std::regex_constants::icase); 
std::regex fromRegex("http://((?:[^@:/]+\\.)?)wik(ipedia|imedia)\\.org/", std::regex_constants::icase); 
std::regex fromRegex("http://([a-z]+\\.)?wik(ipedia|imedia)\\.org/", std::regex_constants::icase); 
std::regex fromRegex("http://([^a]+\\.)?wik(ipedia|imedia)\\.org/", std::regex_constants::icase); 

BU하지 이러한 :

그것은 나에게 아무 의미
std::regex fromRegex("http://([^1-9]+\\.)?wik(ipedia|imedia)\\.org/", std::regex_constants::icase); 
std::regex fromRegex("http://([^@]+\\.)?wik(ipedia|imedia)\\.org/", std::regex_constants::icase); 
std::regex fromRegex("http://([^:]+\\.)?wik(ipedia|imedia)\\.org/", std::regex_constants::icase); 

이 ...

+2

어떤 컴파일러를 사용하고 있습니까? GCC를 포기한다면''*은 구현되지 않습니다 *. 대신 부스트를 사용하십시오. –

+0

나는 어떤 컴파일러도 정규 표현식을 지원하지 않는다는 것을 알지 못했다. 컴파일러에 대한 최근 업데이트입니까? –

+1

@sftrabbit MSVC의 STL은 2008 버전부터 기능적 정규식을 구현했으며 LLVM/Clang의 libC++도 완전한 정규식 구현을 가지고 있습니다. – rubenvb

답변

3

미묘한있다 정규 표현식의 오류. 문자열 리터럴의 이스케이프 시퀀스가 ​​컴파일러에 의해 확장된다는 것을 잊지 마십시오. 그래서, 슬래시 한 쌍의 두 번의 슬래시 각각 대체되는 것을

"http://([^@:/]+\\.)?wik(ipedia|imedia)\\.org/" 

"http://([^@:/]+\.)?wik(ipedia|imedia)\.org/" 

변경.

편집 : 문제는 영향을 미치지 않습니다. (Microsoft와 clang) 시도한 두 가지 구현에서 원래의 문제는 두 배의 백 슬래시가없는 상태에서 발생하지 않습니다. (없으면 유효하지 않은 이스케이프 문자열에 대한 컴파일러 경고가 표시되지만 \.처럼 . 와일드 카드 문자가 \.과 일치합니다.

+1

아니면 기울어 진 이쑤시개 문제를 도와주는 원시 리터럴을 사용하도록 변경하십시오. R "http : // ([^ @ : /] + \.)? wik (ipedia | imedia) \ .org /". 앞의 R. – emsr

+0

@emsr - 원시 리터럴을 지원하는 C++ 11 컴파일러가있는 경우에주의하십시오. –

+0

내 의견이 실제로 잘못되어 삭제했습니다. – Julien

관련 문제