2011-01-09 9 views
3

저는 Ruby 1.9를 사용하고 있습니다.이 작업을 수행 할 수있는 간단한 정규식이 있는지 궁금합니다.문자열의 "키"/ "값"쌍을 켤 수있는 쌍을 가변 할 때 정규 표현식을 사용할 수 있습니까?

str = "Allocation: Random, Control: Active Control, Endpoint Classification: Safety Study, Intervention Model: Parallel Assignment, Masking: Double Blind (Subject, Caregiver, Investigator, Outcomes Assessor), Primary Purpose: Treatment" 

아이디어는 내가 기능적 구성 요소로

  • 할당을이 문자열을 중단하고 싶습니다이다 :
  • 임의

    나는이 일부 변화처럼 많은 문자열이

  • 컨트롤 : Active 컨트롤
  • 엔드 포인트 분류 : 안전성 검토
  • Intervent 이온 모델 : 병렬 할당
  • 마스킹 : 이중 맹검 (주제, 간병인, 탐정, 성과, 감독관)
  • 차 목적 : 문자열이 있는지의 치료

은 "구문"는 " 키 " 하나 이상의"단어 또는 다른 문자 "(예 : Intervention Model) 다음에 콜론 (:)이옵니다. 각 키는 콜론 (:) 바로 뒤에 오는 "값" (예 : 병렬 할당)을가집니다. "값"은 단어, 쉼표 (무엇이든)로 구성되지만 "값"의 끝은 콤마.

키/값 쌍의 수는 가변적입니다. 콜론 (:)이 "값"의 일부가 될 수없고 쉼표 (,)가 "키"의 일부가 될 수 없다고 가정합니다.

하나의 "regexy"방법은이 구성 요소 조각으로 나누기 생각하지만 적절한 일치하는 정규 표현식을 만드는 내 시도는 첫 번째 키/값 쌍을 선택하고 캡처하는 방법을 잘 모르겠습니다. 다른 사람. 다른 성냥을 잡는 방법에 대한 생각? 정규식의

regex = /(([^,]+?): ([^:]+?,))+?/ 
=> /(([^,]+?): ([^:]+?,))+?/ 
irb(main):139:0> str = "Allocation: Random, Control: Active Control, Endpoint Classification: Safety Study, Intervention Model: Parallel Assignment, Masking: Double Blind (Subject, Caregiver, Investigator, Outcomes Assessor), Primary Purpose: Treatment" 
=> "Allocation: Random, Control: Active Control, Endpoint Classification: Safety Study, Intervention Model: Parallel Assignment, Masking: Double Blind (Subject, Caregiver, Investigator, Outcomes Assessor), Primary Purpose: Treatment" 
irb(main):140:0> str.match regex 
=> #<MatchData "Allocation: Random," 1:"Allocation: Random," 2:"Allocation" 3:" Random,"> 
irb(main):141:0> $1 
=> "Allocation: Random," 
irb(main):142:0> $2 
=> "Allocation" 
irb(main):143:0> $3 
=> " Random," 
irb(main):144:0> $4 
=> nil 

답변

6
irb(main):003:0> pp Hash[ *str.split(/\s*([^,]+:)\s+/)[1..-1] ] 
{"Allocation:"=>"Random,", 
"Control:"=>"Active Control,", 
"Endpoint Classification:"=>"Safety Study,", 
"Intervention Model:"=>"Parallel Assignment,", 
"Masking:"=> 
    "Double Blind (Subject, Caregiver, Investigator, Outcomes Assessor),", 
"Primary Purpose:"=>"Treatment"} 

공백 부분은 필요하지만, 약간의 출력을 정리하는 데 도움이되지 않습니다. 키의 끝에서 콜론을 제거하거나 값에서 쉼표를 뒤에 붙여서 제거하는 등의 사소한 정리 작업을 수행하려면이 작업을 맡깁니다.

+1

멋진 답변. – vonconrad

+0

감사합니다. 그것은 효과가있는 것처럼 보이지만 완전히 이해하지는 못합니다. 분할에 대한 메소드 호출 (/ \ s * ([^,] + :) \ s + /)은 기본적으로 "키를 찾아서 분리"라고 말합니다. 그렇다면 어떻게/왜 "분할"하여 키를 배열로 전송합니까? 좋습니다, 그래서 저는 분할 방법에 관해 새로운 것을 배웠다고 생각합니다. str.split (/ : /)을 수행하면 배열에 콜론이 생기지 않습니다. 만약 내가 str.split (/ (:) /), ** ** 콜론 배열에서 얻을 ??? 이것이 분명해야합니까? 나는 b/c에게 그것이 rdoc에서 명백하게 보이지 않는지 물어 본다. – user141146

+0

예, 캡처 그룹이 결과에 포함됩니다.'\ s *'와'\ s +'를 그룹의 바깥에 넣는 것으로, 그것들은 포함되지 않습니다. 'ri String # split'에서 발췌 : _ "pattern이 Regexp 인 경우 str은 패턴이 일치하는 부분으로 나뉘어집니다. 패턴이 길이가 0 인 문자열과 일치 할 때마다 str은 개별 문자로 나뉩니다. 각각의 일치 항목도 배열에 반환됩니다 **. "_ – Phrogz

2

일부 시행 착오 후, 나는 당신의 예를 들어 문자열과 정규 표현식에서 작동하도록 다음 얻을 관리 :

내가 어떤 괄호 안에 쉼표가 무시 될 것이라는 점을 보장하기 위해 내다을 추가했다
str.split(/((?:[^,]+?): (?:[^:]+?,(?![^\(]+?\))))+?/).delete_if(&:empty?).map{|s| s.strip.chomp(',')} 

, 일부 그룹은 음소거됩니다. 끝에있는 delete_ifmap은 순전히 화장품입니다.

관련 문제