2012-04-18 2 views
4

형식이 지정된 문자열에서 정보를 읽습니다. 형식은 다음과 같습니다 : ":"나는 정규식으로 추출 할 수있는 데이터 사이정규식을 이스케이프 처리 된 문자로 구문 분석

"foo:bar:beer:123::lol" 

다. a : 뒤에 다른 문자가 오는 경우 (예 : "::")이 데이터는 ""(빈 문자열)이어야합니다.

현재 나는이 정규식과 구문 분석하고있다 : ":"뿐만 아니라, 데이터 내에 존재
(.*?)(:|$) 

는 지금은 나의 마음에왔다. 그러니 탈출해야합니다. 예 :이 일치하도록

"foo:bar:beer:\::1337" 

가 어떻게 내 정규 표현식을 변경할 수 있습니다 "\"데이터로도?

편집 : JavaScript를 프로그래밍 언어로 사용하고 있습니다. 복잡한 레귤레이션 표현에는 몇 가지 제한이있는 것 같습니다. 솔루션은 JavaScript에서도 작동해야합니다.

덕분에, 맥팔레인

답변

3
var myregexp = /((?:\\.|[^\\:])*)(?::|$)/g; 
var match = myregexp.exec(subject); 
while (match != null) { 
    for (var i = 0; i < match.length; i++) { 
     // Add match[1] to the list of matches 
    } 
    match = myregexp.exec(subject); 
} 

입력 : "foo:bar:beer:\\:::1337"

출력 : ["foo", "bar", "beer", "\\:", "", "1337", ""]

당신은 항상 마지막 경기로 빈 문자열을 얻을 수 있습니다. 이것은 빈 문자열을 구분 기호 (JavaScript에서 보이는 숨김 어설 션의 부족) 사이에서 일치시키려는 요구 사항을 감안할 때 불가피합니다.

설명 : 그것은 : 문자에 따라 토큰에 문자열을 분할

function tokenize(str) { 
    var reg = /((\\.|[^\\:])*)/g; 
    var array = []; 
    while(reg.lastIndex < str.length) { 
    match = reg.exec(str); 
    array.push(match[0].replace(/\\(\\|:)/g, "$1")); 
    reg.lastIndex++; 
    } 
    return array; 
} 

: 여기

(   # Match and capture: 
(?:  # Either match... 
    \\.  # an escaped character 
|   # or 
    [^\\:] # any character except backslash or colon 
)*  # zero or more times 
)   # End of capturing group 
(?::|$) # Match (but don't capture) a colon or end-of-string 
+0

출력 : [ "foo", "bar", "", "beer", "", "\ :", "", "1337", ""] – McFarlane

+0

Ah , 권리. RegexBuddy는 불필요한 빈 일치를 생략 할만큼 "똑똑"하며, JavaScript와 Python (현재 테스트 중이 야)은 그렇지 않습니다. 내가 해결책을 찾을 수 있는지 보자. –

+0

업데이트 된 예제가 예상대로 데이터와 일치하지만 [ "", ""]이 (가) 계속 반환됩니다. 귀하의 예제에서는 루프가 무한 루프가 될 것이므로 일치는 결코 null이 아니기 때문입니다. while 루프는 [subject.match (myregexp) .length-1] 반복을 제한했습니다. 정규 표현식이 굉장하기 때문에 나는 당신의 답을 정확하게 표시 할 것입니다. 당신의 노력에 많은 감사드립니다. – McFarlane

2

부정적인 lookbehind 주장을 사용합니다. 이 \가 선행되지의 경우

(.*?)((?<!\\):|$) 

에만 : 일치합니다.

+0

내 정규식 테스터에서 작동하지만 내 코드에서 작동하지 않습니다. 프로그래밍 언어로 JavaScript를 사용하고 있습니다. 나는 그들을 정의하는 어떤 페이지도 찾을 수 없지만 몇 가지 제한이있는 것으로 보인다. – McFarlane

+3

JavaScript는 lookbehind 어설 션을 지원하지 않습니다. –

+0

그래,'([^ \\] : | $)' –

1

는 솔루션입니다. 당신이 토큰의 일부가 될하려는 경우

  • 는하지만 \: 문자를 탈출 할 수 있습니다. 당신이 다른 \ 해석되지 않습니다 토큰
  • 의 일부가 될하려는 경우
  • 당신은 \\을 피할 수 있습니다. (예 : \a\a입니다.)
  • 따라서 데이터가 올바르게 포맷 된 경우 토큰에 데이터를 넣을 수 있습니다.\a, b, \n, <empty string>, \, :, x : 여기

이 토큰을 제공한다 문자열 \a:b:\n::\\:\::x와 일례이다. 명확하게하기위한 시도에서

>>> tokenize("\\a:b:\\n::\\\\:\\::x"); 
["\a", "b", "\n", "", "\", ":", "x"] 

: 토크 나이에 넣어 문자열은 2 특수 문자를 가지고 해석됩니다 \:

  • \ 만 다음 경우에만 특별한 의미를 갖는 것 \ 또는 :과 같은 문자는 효과적으로 문자를 이스케이프합니다. 즉, tokenizer에 대한 특수한 의미를 잃어 버리며 일반 문자로 간주되어 토큰의 일부가됩니다.
  • :은 2 개의 토큰을 구분하는 마커입니다.

나는 OP가 슬래시 이스케이프를 요구하지 않았지만 다른 뷰어는 데이터의 모든 문자를 허용하는 완전한 구문 분석 라이브러리가 필요할 수 있음을 알고 있습니다.

관련 문제