2012-12-16 2 views
3

목표 :의 모습 ["command", "test/escaped"]분할 OCaml의에서 문자열 -하지만 구분은 백 슬래시로 이스케이프 때

현재 정규 표현식 다음 목록으로 "command/test \/ escaped/"

:는 다음과 같은 문자열을 분할 할 수 있도록 :

너무 simplisitc이고 내가 홍보 탈출 할 필요가

Str.split (Str.regexp "/") string_to_split;;

문자열을 역 슬래시 (;)로 채 웁니다.

나는이 하나의 시도 : Str.regexp "((?!\\).)/"를하지만 맺는 OCaml의 파서 작동하지 않습니다 : uncaught exception Failure("spurious \) in regular expression")

어떤 아이디어? "foobar\/barfoo""foobar\\/barfoo"로 변환된다 : 내가 언급해야

, 나는 OCaml의 파서가 자동으로 그렇게 문자열과 같은 문자열에서 백 슬래시를 이스케이프 나타났습니다. 어쩌면 문자열의 짝수 번째 백 슬래시를 모두 제거하려고 할 수도 있습니다.

답변

3

당신은 두 번 백 슬래시를 이스케이프해야합니다

  • 을 한 번 문자열 내용
  • 에 대해 한 번 정규 표현식

에 대한 그래서 올바른 정규 표현식이 Str.regexp "((?!\\\\).)/"이 될 것입니다.

그러나 정규 표현식이 작동하지 않습니다.

  • 교체, 수동으로 '/' 문자로 간단한 분할을 사용하고, 필요에 따라 문자열을 구도 등 match_beginning,
  • 를 사용

    • 검색 및 분할을 수행

      내가 대신 3 다른 솔루션을 제안 \\§ (또는 처리하려는 텍스트에 나타나지 않는 다른 문자열)을 사용하여 각 문자를 \\/ 자로 분리 한 다음 각 부분 문자열에서 역순으로 바꿉니다 (이번에는 '§'을 '/').

    '/'의 대체 문자가 "\\/" 인 경우 마지막 문자가 가장 빠릅니다.

    let rec split s = Scanf.sscanf s "%[email protected]/%[email protected]\n" (fun left right -> 
        let llen = String.length left in 
        let (left, escaped) = 
        if llen > 0 && left.[llen - 1] = '\\' then 
         (String.sub left 0 (llen - 1), true) 
        else 
         (left, false) in 
        if right = "" then 
        [left] 
        else match split right with 
        h :: t when escaped -> 
         (left^"/"^h) :: t| 
        ht -> 
         left :: ht   
    );; 
    

    그리고 출력 :

  • 1

    는 여기에 약간 덜 확실한 해결책이다

    # split "command/test \\/ escaped/";; 
    - : string list = ["command"; "test/escaped"] 
    

    그것은 너무 비밀 조금,하지만 그럼에도 불구하고 작업을 수행합니다.

    희망이 도움이됩니다.

    0

    AFAIR, Str.regexp! 구조를 지원하지 않습니다.

    그러나 PCRE-OCaml 라이브러리를 수행합니다 을 분할하거나 (더 나은)가 일치를 사용 그리고

    # #directory "+pcre";; 
    # #load "pcre.cma";; 
    # Pcre.split 
        ~rex:(Pcre.regexp ~flags:[`EXTENDED] "(?<!\\\\)/") 
        "command/test \\/ escaped/" 
        ;; 
    - : string list = ["command"; "test \\/ escaped"] 
    

    당신이 \/ 문자열 이스케이프를 제거하려는 경우, 당신은 결과의 후 처리해야 할 것 중 하나 너 자신의 목록을 만들어라.

    관련 문제