2012-04-23 3 views
2

나는 다음과 같이 작업하려고합니다. 그래서 나는 괄호 안에있는 문자열을 가지고 있습니다. 문자열에는 모든 문자가 포함될 수 있으므로 구문 분석하려는 문자열에도 괄호가 포함될 수 있습니다. 정규 표현식은 현재 < ~ ")"과 일치해야하는 마지막 괄호와도 일치하므로 파싱에 실패합니다. 내가 여기서 무엇을 놓치고 있니?임의의 문자를 포함하는 문자열 구문 분석

private def parser: Parser[Any] = a ~ b ~ c ^^ { 
    <do stuff here> 
} 

private def a: Parser[String] = "\"[^\"]*\"".r | "[^(),>]*".r 

private def b: Parser[String] = opt("(" ~> ".*".r <~ ")") ^^ { 
    case Some(y) => y.trim 
    case None  => "" 
} 

private def c: Parser[String] = rep("[email protected]" ~> "[^>.]*".r) ^^ (new String(_).trim) 

이는 문자열의 다음과 같은 종류를 분석하도록되어 :

test0 
[email protected] 
"test2" 
"test3"[email protected] 
test4.. 
[email protected] 
"test6.."[email protected] 
"[email protected]"[email protected] 
test8(icl>uw) 
test9(icl>uw)[email protected] 
"test10..()[email protected]"(icl>uw)[email protected] 
test11(icl>uw(agt>uw2,obj>uw3),icl>uw4(agt>uw5)) 
test12(icl>uw1(agt>uw2,obj>uw3),icl>uw4)[email protected]@attr2 
test13(agt>thing,obj>role>effect) 

는 따라서 "A"파서는 열린 괄호 나까지 문자열을 구문 분석 @ ATTR 부분.. "b"파서는 선택적 괄호 안의 문자를 구문 분석합니다. "c"는 선택적. @ attrs를 구문 분석합니다.
11:07:44.662 [main] DEBUG - Parsed: test8() 
11:07:44.667 [main] ERROR - FAILURE parsing: test8(icl>uw) -- `)' expected but `i' found 

그래서 내가 파서 올바르게 첫 번째 부분을 구문 분석하지만 괄호 부분을봤을 때 실패한다고 가정

은 현재 내가 포함 된 모든 테스트 문자열에 유사한 오류가 발생하는 부분을 괄호. 중첩 된 구조를 구문 분석하는

+2

을 당신은 (아마도) 작은 ** 예를 들어이 질문을 확장 할 필요 ** 당신이 무엇을 그것이 현재 형성되고있는 것처럼 질문에서 분명하지 않기 때문에, 노력하고있는 것은 무엇이며 그것이 작동하지 않는 것입니다. 예 : 문자열 입력'(() '을 가져올 때 발생하는 작업 오류 * 예기치 않은 것 –

+0

예제를 조금 더 명확하게 만들었으므로 본질적으로 괄호 안에있는 내용 – Kitanotori

+0

정규 언어 (결과적으로 정규 표현식)는 중첩 된 괄호를 구문 분석하는 데 사용할 수 없으며 표현이 충분하지 않습니다. 재귀 또는 자동 또는 파서 생성기를 사용하여 다른 기술을 사용해야합니다. – esope

답변

0

오른쪽 솔루션은 다음과 같은 방식으로, 예를 들어, 재귀를 사용하는 것입니다 : 기본적으로 함수를 호출 할 때마다, 당신은 결과 목록에 발견 된 토큰을 추가

val parser= "regex".r 
@tailrec 
def extract(string:String,foundTokens:List[String]=List.empty):List[String]={ 
    parser.findFirstMatchIn(string) match { 
    case Some(parser(matchedValue)) => extract(matchedValue,matchedValue::foundedTokens) 
    case None=>foundTokens 
} 

및 당신은 일치의 결과에 함수를 시작합니다. 더 이상 찾을 수 없으면 발견 된 토큰을 반환합니다. 여러 일치하는 각 subtoken 내부 가능한 경우

, 당신은이 같은 절차 찾아야한다 :

def extract(string:String):Iterator[String]={ 
    parser.findAllIn(string).flatMap{ 
     item => extract(item) 
    } 
}