2014-06-23 4 views
0

응용 프로그램을 개발 중입니다. 사용자가 서버에 일부 설정 값을 입력합니다. inbuilt API를 통해 서버에 값을 요청할 때. 나는 전체 문자열로 같은 값을 얻고있다 :
여기
다음 시나리오에서 정규식 일치 문제가 발생했습니다.

name={abc};display={xyz};addressname={123} 

예 -에 대한 속성 내가 함께 분할하는 데 사용되는 이름, 표시 및 주소가 각각의 값입니다 abc 방송, XYZ 및 123
가있다 ; 첫 번째 delimeter로 =와 두 번째 dleimeter로.

String[] propertyValues=iPropertiesStrings.split(";"); 
     for(int i=0;i<propertyValues.length;i++) 
     { 
      if(isNullEmpty(propertyValues[i])) 
       continue; 

      String[] propertyValue=propertyValues[i].split("="); 
      if(propertyValue.length!=2) 
       mPropertyValues.put(propertyValue[0], ""); 
      else 
       mPropertyValues.put(propertyValue[0], propertyValue[1]); 
     } 
    } 

여기 mPropertyValues ​​속성 이름과 값을 유지하기 위해 사용되는 해시 맵입니다.

경우 1 :

case 1: name={abc};display={ xyz=deno; demo2=pol };addressname={123} 
case 2: name=;display={ xyz=deno; demo2=pol };addressname={123} 

내가 해시 맵이 가득 싶은 :

문제는 문자열이있을 수있다

name ="" 
display = "xyz= demo; demo2 =pol" 
addressname = "123" 
: 경우 2

name ="abc" 
display = "xyz= demo; demo2 =pol" 
addressname = "123" 

이러한 문자열을 분할하는 정규 표현식을 찾고 있습니다.

+2

중괄호 세트에는 중첩 된 중괄호가 포함될 수 있습니까? 'name = {abc = {x}; xyz = {12}}'에서와 같이? 그렇다면 문법은 재귀 적이며 정규식 파싱에 적합한 후보는 아닙니다. 상태 기계 또는 재귀 파서를 작성해야합니다. –

답변

0

:

name-> 
display->xyz=deno; demo2=pol 
addressname->123 

설명이

(?<name>\\w+)=(\\{(?<value>[^}]*)\\})?(;|$)이 부분으로 분할 할 수있는

  • (?<name>\\w+)=는 XXXX를 나타내고 =하고 name (속성)
  • (\\{(?<value>[^}]*)\\})?X}가 아닐 수있는 선택적 {XXXX} 일부라는 그룹 XXXX를 배치했다. 또한 value이라는 그룹에 XXXX 부분이 있습니다. 수식 name=value;name=value 또는 데이터의 끝에 배치 쌍 경우이므로
  • (;|$)은 ($ 앵커로 표시되는) 데이터 ; OR 단부를 나타낸다.
0

다음 정규식은 조건과 일치해야하며 명명 된 캡처 그룹을 사용하여 필요한 세 가지 값을 가져옵니다.

name=\{(?<name>[^}])\};display=\{(?<display>[^}]+)\};addressname=\{(?<address>[^}]\)} 
0

데이터 집합을 변경할 수 있습니다 가정은 더 나은 파서는 반환 형식에서 발견되는 어떤에서 Map를 구축, 더 역동적 일 수 있습니다.

(다른 언급이, 그리고 {}없이 중첩) 이것에 대한 정규식 위에 나열 경우 주어진 아주 간단합니다 :

Matcher m = Pattern.compile("(\\w+)=(?:\\{(.*?)\\})?").matcher(source_string); 
while (m.find()) { 
    if (m.groupCount() > 1) { 
     hashMap.put(m.group(1), m.group(2)); 
    } 
} 

있다, 그러나, 이에 대한 고려 사항 :

  1. m.group (2)가 존재하지 않으면 "null"이 값이됩니다 (논리 값이 작은 경우 원하는 값으로 조정할 수 있습니다).
  2. 향후 데이터가 변경 될 경우를 대비하여 다양한 데이터 세트를 고려해야합니다.

그 정규식 기능 :

  1. (\\w+) -이 행 (A-Z_) 하나 개 이상의 단어 문자를 찾습니다 및 "캡처 그룹"로두고 (group(1))
  2. = - 리터럴은
  3. (?:...)?과 같습니다. 이렇게하면 그룹화가 캡처 그룹이 아니며 (.group(n)이 아니며 후행 ?은 선택적 그룹화입니다.
  4. \\{(.*?)\\} - 리터럴 {} 사이의 항목을 찾습니다 (참고 : 여기에 빗살 무늬가있는 경우 }이 깨집니다). 이 섹션이있는 경우 {} 사이의 내용은 두 번째 "캡처 그룹"(.group(2))에 있습니다. 당신이

    String data = "name=;display={ xyz=deno; demo2=pol };addressname={123}"; 
    
    Pattern p = Pattern.compile("(?<name>\\w+)=(\\{(?<value>[^}]*)\\})?(;|$)"); 
    Matcher m = p.matcher(data); 
    
    while (m.find()){ 
        System.out.println(m.group("name")+"->"+(m.group("value")==null?"":m.group("value").trim())); 
    } 
    

    가 출력 무엇을해야한다 {}이이 중첩 될 수 없다는 가정