2011-02-08 6 views
1

내가 일치 시키려면 다음과 같은 형식의 n 개의 문자열을 포함하는 문자열을 다음과 같이자바 정규식 도움

{varName:param1, param2, param2} 

요구 사항은 다음과 같습니다

  1. 만 변수 varName을 (중괄호 내부) 필수적입니다
  2. 매개 변수 개수에 제한이 없습니다
  3. 공백을 포함해서는 안되는 var 및 param 이름을 제외한 중괄호 안의 공백은 제한되지 않습니다.

varName 및 각 매개 변수를 별도로 캡처 할 수 있기를 바랍니다.

저는 거의 거기에있는 정규식을 생각해 냈습니다. 어떤 도움을 주시면 감사하겠습니다.

+1

당신은 "거의 거기"인 정규식을 가지고 있다고 말합니다. 아마도 지금까지 관리했던 것을 게시 할 수 있습니까? –

+0

이 문제는 varName (group1)과 첫 번째 매개 변수 (group2) 및 마지막 매개 변수 (group3)가 – Tom

+0

\ {([a-zA-Z] +) (?: \ s * : \ s * : \ s * : \ s * ([^, \ s] +))? (? : \ s *, \ s * ([^, \ s] +)) * \ s * \} – Tom

답변

1
String s = "blah blah\n{varName:param1, param2, param2}\nblah"; 

Pattern p = Pattern.compile(
    "\\{([a-zA-Z]+)(?:\\s*:\\s*([^,\\s]+(?:\\s*,\\s*[^,\\s]+)*))\\}" 
); 
Matcher m = p.matcher(s); 
if (m.find()) 
{ 
    String varName = m.group(1); 
    String[] params = m.start(2) != -1 
        ? m.group(2).split("[,\\s]+") 
        : new String[0]; 

    System.out.printf("var: %s%n", varName); 
    for (String param : params) 
    { 
    System.out.printf("param: %s%n", param); 
    } 
} 

문자열을 일치시키고 모든 구성 요소를 하나의 정규식으로 구분하는 방법을 고집하는 경우 신경 쓰지 마세요. 이것은 얻을 수있는만큼 좋다 (Perl 6로 전환하지 않는 한). 성능에 관해서는 문제가 될 때까지 걱정하지 않을 것입니다.

+0

네, 도와 주신 모든 분들께 감사드립니다. 나는 내가 잘못된 나무를 짖고있는 것을 보았습니다. – Tom

2

위의 경우 regexps와의 전투보다는 단순히 String.split()을 사용하는 것이 더 쉬울 것인지 궁금합니다. 구분 기호 (콜론/공백/쉼표)는 잘 정의 된 것처럼 보입니다.

+0

아마, 내가 주변 문자열에 전체 패턴을 찾을 정규식을 사용해야하지만, 내가뿐만 아니라 같은 시간에 내부 부품을 일치 수도 생각 – Tom

+0

동의, 정규식 정말이 문제에 대한 해결책이되지 않습니다. 읽을 수없는 oneliners (및 다른 정규식이 있습니까?) 유지하기가 끔찍하며 구문은 몇 줄에서 쉽게 파싱 될만큼 간단합니다. – Voo

0

당신이 지금까지 가지고있는 것을 게시하십시오. 다음 웹 사이트에서 매우 쉽게 테스트 할 수 있습니다. http://www.regexplanet.com/simple/index.html

+0

내가 지금까지 가지고있는 것을 더했다 – Tom

1

정규 표현식 및 스캐너는 어떻습니까? psuedocode의

import java.util.Scanner; 

public class Regex { 

    public static void main(String[] args) { 
    String string = "{varName: param1, param2, param2}"; 
    Scanner scanner = new Scanner(string); 
    scanner.useDelimiter("[\\s{:,}]+"); 
    System.out.println("varName: " + scanner.next()); 
    while (scanner.hasNext()) { 
     System.out.println("param: " + scanner.next()); 
    } 
    } 
} 
+0

재미있는 점은 이전에 스캐너 클래스를 보지 못했다는 것이다. 그것에 지금 읽는. – Tom

1

빠른 해결책 :

\ {\의 *를 ([^ \ {: 난 그냥 잘 작동하는 것 같다 정규식에서 솔루션을 가지고 좋아

string.match(/{(\w+):([\w\s,]+)}/); 
varName = matches[1]; 
params = matches[2].split(','); 
+0

네, 그 생각을 포기하고 그것을하기 전에이 게시물은 마지막 만세였습니다. 꽤 높은 볼륨이 될 것이기 때문에 별도의 분할 성능에 대해서는 조금 걱정할 것입니다. 그러나 tbh에 대해서는 잘 모릅니다. – Tom

0

\ s * ([: \ {\}, \ s] +) \ s * ? \} \ S] +)는 \ s에 *) *) \}

심지어 그것을 이해할 수있는의 구실 유지 :

NAME = [^ \ {\} \ S] +

WS = \ S *

\ {WS (이름) WS (?? (WS : (이름) WS) (? ?, WS (이름) WS는) *) \}

나는 그것을 권하고 싶지 않다 그러나 짧은 테스트는 작동을 나타 내기 위해 보인다 - 아침에 오전 3시에 대한 좋은 수수께끼를)

PS를 : 당신이 만약 분할 솔루션을 이와 비슷하게 비교하는 것은 성능 차이가 있다면 청력에 관심이있을 것입니다. 저는 정규 표현식이 특히 효과적이라고 생각하지 않습니다.