2013-01-18 2 views
0

정규식을 사용하여 <tag>=<value> 타입의 문자열을 구문 분석하려고하지만 인용 된 값에 대한 지원을 추가하는 데 문제가 발생했습니다. 아이디어는 인용 부호로 둘러싸이지 않은 값이 [ Hello ][Hello]이된다 그래서 공백 뒤에/선도의 손질해야한다는 것입니다 (Pls는 대괄호를 무시한다.) 그러나정규식을 사용하여 따옴표 붙은 값과 따옴표없는 값 추출하기

, 값이 인용 될 때, 나는 및 이중 등까지 무엇이든 원하는 제거 할 인용하지만, 더, 그래서 [ " Hello World " ]이 될 수 없을 것입니다 [" Hello World "]

지금까지, 나는 이것에 대한 패턴 일치 (문자 중 일부는 탈출 또는 이중 피하기 위해 탈출 한주의 다음과 같은 코드로 왔어요 트라이 그래프 또는 다른 C 형식 문자로 해석됩니다.)

void getTagVal(const std::string& tagVal) 
{ 
    boost::smatch what; 
    static const boost::regex pp("^\\s*([a-zA-Z0-9_-]+)\\s*=\\s*\"\?\?([%:\\a-zA-Z0-9 /\\._]+?)\"\?\?\\s*$"); 

    if (boost::regex_match(tagVal, what, pp)) 
    { 
     const string tag = static_cast<const string&>(what[1]); 
     const string val = static_cast<const string&>(what[2]); 

     cout << "Tag = [" << tag << "] Val = [" << val << "]" << endl; 
    } 
} 

int main(int argc, char* argv[]) 
{ 
    getTagVal("Qs1= \" Hello World \" "); 
    getTagVal("Qs2=\" Hello World \" "); 
    getTagVal("Qs3= \" Hello World \""); 
    getTagVal("Qs4=\" Hello World \""); 
    getTagVal("Qs5=\"Hello World \""); 
    getTagVal("Qs6=\" Hello World\""); 
    getTagVal("Qs7=\"Hello World\""); 

    return 0; 
} 
이중 이스케이프를 촬영

,이로 분해 :

  • ^ - 라인의 시작.
  • \s* - 선택 사항 인 공백입니다.
  • ([a-zA-Z0-9_-]+) - 하나 이상의 영숫자 또는 대시 또는 밑줄. 이것은 태그로 캡처됩니다.
  • \s* - 선택 사항 인 공백입니다.
  • = - "동일한"기호.
  • \s* - 선택 사항 인 공백입니다.
  • "?? - 선택 사항 인 큰 따옴표 (비 탐욕심).
  • ([%:\a-zA-Z0-9 /\._]+?) - 하나 이상의 영숫자 또는 공백, 밑줄, 백분율, 콜론, 마침표, 정방향 또는 백 슬래시. 이것은 (욕심이 아닌) 값으로 파악됩니다.
  • "?? - 선택 사항 인 큰 따옴표 (비 탐욕심).
  • \s* - 선택 사항 인 공백입니다.
  • $ - 예를 들어 라인

의 끝은 내가 얻을 기대, main()에서 호출

Tag = [Qs1] Val = [ Hello World ] 
Tag = [Qs2] Val = [ Hello World ] 
Tag = [Qs3] Val = [ Hello World ] 
Tag = [Qs4] Val = [ Hello World ] 
Tag = [Qs5] Val = [Hello World ] 
Tag = [Qs6] Val = [ Hello World] 
Tag = [Qs7] Val = [Hello World] 

을하지만 실제로 얻을 것은 : 그래서 그것의

Tag = [Qs1] Val = [" Hello World ] 
Tag = [Qs2] Val = [" Hello World ] 
Tag = [Qs3] Val = [" Hello World ] 
Tag = [Qs4] Val = [" Hello World ] 
Tag = [Qs5] Val = ["Hello World ] 
Tag = [Qs6] Val = [" Hello World] 
Tag = [Qs7] Val = ["Hello World] 

거의 정확하지만 어떤 이유 때문에 첫 번째 인용구가 출력 값에 매달려 있습니다. 그 바깥쪽에 따옴표가있는 egex.

+0

당신은 텍스트와 일치하는 데 사용하는 우리에게 코드를 보여줍니다 (즉, 당신이 그것을 \\\\을 만들 필요) – Anirudha

+0

@ Some1.Kill.The.DJ : 지금 거기에 있어야합니다. –

답변

1

내가 대안에 대한 첫 번째 따옴표로 시작하는 부분을 변경합니다 :

"([^"]+)"|([%:\a-zA-Z0-9 /\._]+)\s* 

당신은 다음의 두 가지 가능성을 처리해야 인용 또는 인용 부호가 텍스트에서 두 번째 또는 세 번째 캡처 괄호 쌍에 종료 호스트 코드를 정규식 주위에.

+0

@ 프랑크푸 : 고마워요. 그러나 나는 그것을 알아 냈다고 생각합니다. –

0

문제가 무엇인지 알아 냈습니다.

\를 사용하는 경우이는 C 문자열 내에서 처리 등이 탈출해야 될 때 조심해야하지만주의하지 않으면, 그래서 그것은 또한 정규식 엔진에 의해 처리됩니다 \\a입니다 \a된다 절대적으로 당신이 원하는 것이 아닙니다.

그래서 \을 값의 문자 집합에 포함시키고 싶습니다 (아이러니하게도, 형식 문자열 내에서 이스케이프 시퀀스로 사용됨). 그러면 이중 이스케이프해야합니다 그 때문에

static const boost::regex pp("^\\s*([a-zA-Z0-9_-]+)\\s*=\\s*\"\?\?([%:\\a-zA-Z0-9 /\\._]+?)\"\?\?\\s*$"); 

가된다 :

static const boost::regex pp("^\\s*([a-zA-Z0-9_-]+)\\s*=\\s*\"\?\?([%:\\\\a-zA-Z0-9 /._]+?)\"\?\?\\s*$"); 

관련 문제