2012-01-08 4 views
5

이 정규식을 이해하려고하는데, 도와 줄 수 있습니까? (?s) 내가 이해하지 못하는 정규식

  • 왜 이중 \\} 전을 :

    (?s)\\{\\{wotd\\|(.+?)\\|(.+?)\\|([^#\\|]+).*?\\}\\} 
    
    • 정말 DOTALL의 의미를 이해하지? 이 정확히 의미합니까 무엇
    • : (.+?)는 (우리는이 같은을 읽어야 할 사람 :?를 ., 다음 +.+
  • +4

    당신이 볼 수있는 소스에 리터럴 문자열에 도트가 더 이상 사용되지 않는 때문에 DOTALL 수정이뿐만 아니라 사라졌다합니다 ? 예를 들어 패턴 p = Pattern.compile ("(? s) \\ {\\ {wotd \\ | (. +?) \\ | (. +?) \\ | ([^ # \\ |] +). *? \\} \\} ");'? 왜냐하면 역 슬래시는 문자열 리터럴과 정규 표현식 모두에서 이스케이프되므로 '\\ {'을 해석하기 위해 '\\ { "'(이 경우'\\'가 패턴 컴파일러는 이스케이프 된 백래시와 이스케이프 된 백 슬래시가 뒤에 오는'{') 또는'\\ {'(예 : 텍스트 파일이나 다른 것으로부터 읽힌 것) {'. –

    +0

    '. +?'는 욕심이없는 ("꺼려하는")'+'연산자입니다. '\\\'는 리터럴 백 슬래시를 의미합니다. 정규 표현식이 Java이고 자바 문자열에 삽입 된 경우 첫 번째'\\ '는 두 번째를 이스케이프 처리합니다. –

    답변

    8

    이 정규식 문자열 출신의 결과에 응답 한 후 ?.에 작용합니다. "정식"정규식은 다음과 같습니다

    (?s)\{\{wotd\|(.+?)\|(.+?)\|([^#\|]+).*?\}\} 
    

    DOTALL 수정이 점은 또한 적어도 자바, 문자 클래스를 보완 할 수 있도록 개행 문자와 일치하지만 수 있다는 것을 의미한다 : 즉 [^a]a이 아닌 모든 문자를 매치하고 개행을 포함합니다. 일부 정규식 엔진은 보완 된 문자 클래스의 개행 문자와 일치하지 않지만 (이것은 버그라고 볼 수 있습니다).

    +?*?은 일반적으로 피해야하는 지연 수량 자입니다. 즉,이 캐릭터가 정규 표현식의 다음 구성 요소를 만족시킬 수 있는지를보기 위해 삼키고 싶은 각 캐릭터 앞에 기대해야합니다. {...} 반복 정량 때문에

    {}\ 앞에는 사실은 {N, m} n 및 m은 정수가 어디에.

    또한 파이프 |을 문자 클래스 [^#\|]에서 벗어나는 것은 쓸모 없으며, 간단히 [^#|]으로 기록 할 수 있습니다.

    마지막으로 .*?은 나머지 필드를 삼키는 것으로 보입니다. 더 나은 대안은 normal* (special normal*)* 패턴을 사용하는 것입니다. 여기서 normal[^|}]이고 special\|입니다.

    여기에 게으른 한정 기호, "고정 된"문자 클래스 및 수정 된 끝을 사용하지 않는 정규식이 있습니다.

    \{\{wotd\|([^|]+)\|([^|]+)\|([^#|]+)[^|}]*(?:\|[^|}]*)*\}\} 
    

    단계 단계에서 :

    \{\{   # literal "{{", followed by 
    wotd   # literal "wotd", followed by 
    \|   # literal "|", followed by 
    ([^|]+)  # one or more characters which are not a "|" (captured), followed by 
    \|   # literal "|", followed by 
    ([^|]+)  # one or more characters which are not a "|" (captured), followed by 
    \|   # literal "|", followed by 
    ([^#|]+)  # one or more characters which are not "|" or "#", followed by 
    [^|}]*  # zero or more characters which are not "|" or "}", followed by 
    (?:   # begin group 
        \|   # a literal "|", followed by 
        [^|}]*  # zero or more characters which are not "|" or "}" 
    )   # end group 
    *   # zero or more times, followed by 
    \}\}   # literal "}}" 
    
    +0

    게으른 한정 기호를 사용하지 않는 이유는 무엇입니까? – Lucero

    +0

    정규 표현식은 원본과 동일하지 않습니다. 원본은 당신이하지 않을 많은 문자열과 일치합니다. 추측해야만한다면 버전이 정규 표현식 작성자의 원래 의도에 더 가깝다는 것을 추측 할 수 있지만 요구 사항이 무엇인지 모른 채 확실하게 알 수있는 방법은 없습니다. (그리고 어쨌든 버전이'.'을 사용하지 않기 때문에 당신의 버전에서'(? s)'를 제거 할 수도 있습니다. – ruakh

    +0

    마지막'. *? '은 다른 파이프들 또한 이스케이프 처리됩니다 (최종 정규식이 삭제됩니다). ''{wotd | field1 | field2 | some_stuff # 아마도 코멘트가 무엇입니까? ' – user268396

    관련 문제