2012-05-03 4 views
-4

JSON 및 JavaScript를 기반으로 DSL을 만들고 있는데 키 값을 '원시'로 지정하고 문자열 구분 기호로 묶지 않아야합니다. 희망이 설명 빠른 예 :객체로 구문 분석하기 전에 JSON을 수동으로 파싱

{myKey:custom_function('arg1'), myKey2:custom_function("another arg1")} 

{myKey:"custom_function('arg1')", myKey2:"custom_function(\"another arg1\")"} 

JSON 개체를 구문 분석시, custom_function이 존재하지 않기 때문이다 될 것이다. 나는 값을 평가하지 않고 JSON을 구문 분석 할 수 있어야하고, 키를 반복 할 때마다 값을 하나씩 만 확장해야한다.

두 번째 코드 단편을 두 번째 코드 단으로 전환하는 데 사용할 수있는 정규식 또는 다른 방법은 무엇입니까?

나는 더 간단한 해결책이 케이스의 90 %를 덮을 것이라고 가정하고 있지만, 방탄 구현을 작성하는 것은 많은 노력을 필요로 할 것입니다. 내가 자바 스크립트의 정규 표현식 지원 (applessly lookbehind 기능 없음)에 대한 연구를 기반으로하면, 정규식 패턴이 1 ~ 2 라인 이상 필요하다고 가정하고 있습니다.

또한 노드 응용 프로그램을위한 것이므로 모든 트릭이 유용합니다.

편집 :

이 질문은 몇 가지 downvotes을 받고있는 것 같다,하지만 난 미래 명의 Google/내 자신의 참조의 이익을 위해 어쨌든 그것을 떠 났어요. 어떤 방법/기법이 이런 종류의 문제에 가장 잘 작동하는지에 대한 질문은 완벽하게 유효합니다. 비슷한 문제에 직면 한 다른 노드/js 신규 이식자가 쉽게 생길 수 있습니다.

+0

미안 해요하지만하는 DSL은 무엇인가? –

+0

도메인 특정 언어. 사용자가 응용 프로그램을 지시하는 스크립트를 작성할 수있는 기능이있는 복잡한 비즈니스 사례입니다. – Trindaz

+0

DSL이 DSL 하이브리드 JSON 모델이기 때문에 downvotes가 느껴진다. JSON을 DSL로 사용하는 것보다 훨씬 의미가있다. DSL은 단지 JSON 표준이어야한다고하는 경영진의 주장에 따르면 요점은 관리가 쉽고, 미래 보장되며, 구현하기가 더 쉽다는 점입니다. – balupton

답변

0

최종 답변 : 정규식은 이처럼 복잡한 작업에는 적합하지 않습니다. 온라인에서 발견 한 비슷한 복잡한 솔루션 (예 : 코드 주석 제거)은 주로 정규식을 사용하지 않고 주로 사용자 지정 반복 접근 방식을 사용했기 때문에 유사한 접근 방식이이 상황에서 너무 고통스럽지 않았습니다.

그래서 결국 찾을 수있는 '최상의'방법은 매우 많은 정규 표현식이나 노드의 특수 라이브러리 또는 문제에 적합한 다른 라이브러리를 포함하지 않았습니다.

마지막으로, 비슷한 문제가있을 수 있습니다 미래 명의 Google의 이익을 위해, 내가 https://gist.github.com/2590689에서 내 솔루션을 게시했습니다 아래에 복사 :

//clothe a hub file that has 'naked' expressions 
//e.g. turn {key:$('body p')} into {key:"$('body p')"} 
function clothe(contents){ 

closers = /[\}\]\)\/"']/ 
openers = /[\{\[\(\/"']/ 
closing = { 
    "{": "}", 
    "[": "]", 
    "(": ")", 
    "/": "/", 
    '"': '"', 
    "'": "'" 
} 

contents = contents.split(""); 

var beforeKey = true; 
var inKey = false; 
var beforeValue = false; 
var inValue = false; 
var inArray = false; 
var delimiterStack = []; 

function inDelimited(){ 
    return delimiterStack.length > 0; 
} 

function toggleDelimiter(d){ 
    if(openers.exec(d) && !closers.exec(d)){ 
     pushDelimiter(d); 
    }else if(openers.exec(d) && closers.exec(d)){ 
     if(topDelimiter()){ 
      if(topDelimiter()==d){ 
       popDelimiterIfValid(d); 
      }else{ 
       pushDelimiter(d); 
      } 
     }else{ 
      pushDelimiter(d); 
     } 
    }else if(closers.exec(d)){ 
     popDelimiterIfValid(d); 
    } 
} 

function topDelimiter(){ 
    if(delimiterStack.length>=0){ 
     return delimiterStack[delimiterStack.length-1]; 
    }else{ 
     return undefined; 
    } 
} 

function pushDelimiter(d){ 
    delimiterStack.push(d); 
} 

function popDelimiterIfValid(d){ 
    if(delimiterStack.length>0) 
     if(closing[delimiterStack[delimiterStack.length-1]]==d) 
      delimiterStack.pop(d); 
} 

function rTrimmedRightBound(rightBound){ 
    while(rightBound>0){ 
     if(!/\s/g.exec(contents[--rightBound])){ 
      return rightBound+1; 
     } 
    } 
} 

for(var i=0; i<contents.length; i++){ 

    function delimiterCheck(c){ 
     if(c=='"'){ 
      toggleDelimiter('"'); 
      contents.splice(i, 0, '\\'); 
      i++; 
     }else if(openers.exec(c) || closers.exec(c)){ 
      toggleDelimiter(c) 
     } 
    } 

    if(beforeKey){ 
     if(/[a-zA-Z0-9$_!]/.exec(contents[i])){ 
      beforeKey = false; 
      inKey = true; 
     } 
    }else if(inKey){ 
     if(contents[i]==":"){ 
      inKey = false; 
      beforeValue = true; 
     } 
    }else if(beforeValue){ 
     if(/[a-zA-Z0-9$_!'"\(\/]/.exec(contents[i])){ 
      contents.splice(i, 0, '"'); 
      i++; 
      beforeValue = false; 
      inValue = true; 
      delimiterCheck(contents[i]); 
     }else if(/\{/.exec(contents[i])){ 
      beforeKey = true; 
      beforeValue = false; 
     }else if(/\[/.exec(contents[i])){ 
      beforeValue = false; 
      inArray = true; 
     } 
    }else if(inArray && !inValue){ 
     if(/[a-zA-Z0-9$_!'"\(\/]/.exec(contents[i])){ 
      contents.splice(i, 0, '"'); 
      i++; 
      beforeValue = false; 
      inValue = true; 
      delimiterCheck(contents[i]); 
     } 
    }else if(inValue){ 
     if(!inDelimited() && /[\},\]]/.exec(contents[i])){ 
      contents.splice(rTrimmedRightBound(i), 0, '"'); 
      i++; 
      inValue = false; 
      if(/\]/.exec(contents[i])){ 
       inArray = false; 
      } 
      beforeKey = !inArray; 
     }else{ 
      delimiterCheck(contents[i]); 
     } 
    } 
} 

return contents.join(""); 
} 
관련 문제