2016-07-14 3 views
1

키 - 값 쌍 (고정되지 않은 키 - 값 쌍 유형의 순서와 함께 고정되지 않은 키 - 값 쌍의 수)이있는 스칼라 문자열이 주어진 경우스칼라 문자열에서 토큰을 빠르게 추출하는 방법

val s = "key1: val1, key2: (val2.1, val2.2, val2.3), key3:(), key4: val4" 

내가 좋아하는 불변의 맵에이를 꺼내해야합니다

val kvMap = s.split(", ").map(_.split(": ")).map(t => t(0) -> t(1)).toMap 

:

Map("key1" -> "val1", 
    "key2" -> "(val2.1, val2.2, val2.3)", 
    "key3" -> "()", 
    "key4" -> "val4") 

나는이 시도했다 그러나 대괄호와 키 - 값 쌍 사이에 동일한 구분 기호 (쉼표)가 사용 되었기 때문에 실패했습니다.

반복을 사용하여 스택을 사용하여 수행 할 수는 있지만이를 방지하고 싶습니다.

scala> val MyPattern = "([^=]*):(.*)".r 
Pattern: scala.util.matching.Regex = ([^=]*):(.*) 
         ^
scala> val MyPattern(k, v) = "key: value" 
k: String = key 
v: String = " value" 

을 나는이 작업을 할 수있는 기능적인 방법을 찾고 있어요 :

은 또한 나를 이렇게 도움이 될 수 있지만 그것은 단지 1 쌍에 대해 작업을 얻을 수있는 정규식을 작성하는 시도했습니다.

답변

5

중첩 된 괄호가없는 키 값 쌍, 당신은 ( 이외의 문자로 다음과 ) 최대 ) A와하지 않는 + 공간 쉼표로 분할 정규식을 사용할 수있는 경우 :

""", (?![^()]*\))""".r 

regex demo

설명을 참조하십시오 :

  • , - (에 따르지 않을 경우 즉, 리터럴 ) 뒤를 ) 비 및 비 ) (0 회 이상)에 따르지 -
  • (?![^()]*\)) 콤마와 그 뒤에 공간을 경우에만 일치 ... 뭔가 + )).

당신이 일치하는 접근 방식을 시도 할 경우

"""([^=:]*):\s*(.*?),?\s*(?=$|\w+:)""".r 

this demo

세부 참조 :

  • ([^=:]*)-= 이상의 그룹 1 캡처 0+ 문자 다른 및 : (아마도키가)
  • :\s* 비어있을 수 없기 때문에는 +로 대체해야 - 옵션에 따라되는) 그룹 2, (.*?) (가능한 한 적은 수의 모든 문자하지만 줄 바꿈 - 0+ 공백
  • (.*?),?\s*와 콜론 , 및 0+ 공백 ...
  • (?=$|\w+:) - 그 뒤에는 문자열의 끝 또는 1 자 이상의 단어와 콜론이옵니다.
+1

완벽! 이것은 대단하다! –

관련 문제