2014-03-02 2 views
2

안녕하세요. 저는 약간의 문제가 있습니다.패턴 배열에서 찾고 방법을 실행하십시오.

문자열에서 약 200 개의 정규식 패턴을 확인하고 패턴을 실행하여 메소드를 실행해야합니다. 그냥 내가 필요한 것을 취소하려고

Pattern pattern = Pattern.compile([Array of patterns]); 
Matcher matcher = pattern.matcher(str); 
while (matcher.find()) { 

Pattern p = matcher.pattern(); 
p.runSomeMethod(); 
} 

물론, 위의 코드는 그것을 할 수있는 방법이되지 않습니다 : (반 사이비) 같은 것을 의미

.

내 문제는 String 또는 Pattern 중 하나를 확장해야한다는 것이고, 실제 문제는 두 가지가 모두 final이므로 수행 할 수 없다는 것입니다.

기본적으로 내가하려는 것은 문자열에 여러 개의 패턴이있는 경우 1 개만 들어 맞고 선택된 패턴을 기반으로 프로 시저를 실행하여 막대한 전환 사례를 피하려고합니다. 패턴이 내 클래스의 객체를 반환 할 여러 클래스를 구현하면 메소드 만 실행합니다.

어떤 생각을 어떻게 할 수 있습니까? 주제에 대한 정보는 거의 찾지 못했습니다.

답변

1

한 가지 방법이있을 것이다하지만 '공장 패턴'조합의 전략 패턴을 사용하는 것입니다을 공개하지 않고 올바른 인스턴스를 만들려면 이 같은 익명의 내부 클래스와 함께 :

private Map<Pattern, Runnable> patterns; 
{ 
    { 
     patterns = new LinkedHashMap<Pattern, Runnable>(); 
     patterns.put(Pattern.compile("\\w+"), new Runnable() { public void run() { System.out.println("word"); } }); 
     patterns.put(Pattern.compile("\\d+"), new Runnable() { public void run() { System.out.println("number"); } }); 
    } 
} 

public void matchAndExecute(String str) { 

    Iterator<Entry<Pattern, Runnable>> it = patterns.entrySet().iterator(); 
    while (it.hasNext()) { 
     Entry<Pattern, Runnable> pattern = it.next(); 
     if (pattern.getKey().matcher(str).matches()) { 
      pattern.getValue().run(); 
     } 
    } 
} 
+0

하지만 실행 시간에 컴파일해야하기 때문에 200+ 정규식으로 갈 때 실제로 느려지지 않을까요? 모든 구현을 파일로 만들고 미리 정의 된 해시 맵을 만들면 더 빨리 실행될 것이라고 가정합니다. 가능한가? –

+0

Regexes는 항상 런타임에 컴파일됩니다. 이 메서드는 클래스 이니셜 라이저를 사용하므로 클래스 초기화 중에 정규식이 한 번만 컴파일됩니다. 현대의 모든 머신은 마이크로 초 범위에서 200 개의 정규식을 컴파일합니다. regexes를 실행하는 가장 좋은 순서를 예측하거나 더 똑똑한 매칭 알고리즘을 생성하기를 원하지 않는 한, 이것보다 더 빨리 얻을 수는 없습니다. 둘 다 매우 어렵습니다. –

+0

이것은 제 생각과 같습니다. 패턴의 순서가 중요하더라도 LinkedHashMap 또는 쌍 목록을 사용합니다. –

0

패턴 및 Runnable/Callable에 대한 키를 사용하여 (LinkedHash) 맵을 만드는 방법은 무엇입니까? 그게 너에게 도움이 되겠니? 그런 식으로지도를 방문하고 키가 일치/발견되면 값을 실행합니다.

+0

예, 저것은 저의 최악의 시나리오 일 것입니다. 것은 내가 실행하고 싶습니다 방법은 꽤 복잡하고 코드를 더 잘 정리하고 싶습니다, 나는 오히려 "객체 지향"솔루션을 찾을 것입니다 –

+0

저는 동적 (OOP) 언어를 생각합니다 메서드 호출에 대해 비슷한 기술을 사용하므로 객체 지향 솔루션과 너무 다른 형식이 아닙니다. –

0

당신은 strategy 패턴을 봐야합니다.

interface을 구현하고 pattern 일치를 기반으로 적절한 방법을 호출 할 수 있습니다.

보통 로직 시도 당신이 당신의 로직을 작성하려면이 옵션을 달성하기 위해

http://www.dotnetperls.com/factory

+0

예. 올바른 패턴을 만들기 위해 일치하는 패턴을 어떻게 알 수 있습니까? –

+0

@ eric.itzhak는 인스턴스의 로직을 캡슐화 할 수있는 팩토리 패턴 일 수 있습니까? – Dexters

1

당신은이에 대한 Map 필요하지 않습니다, 단지 클래스 패턴 및 Runnable를 모두 들고 만들고을 채우기(또는 배열)을 선택하십시오.

class PatternMatcher { 
    private Pattern pattern; 
    private Runnable runnable; 

    public PatternMatcher(PatternMatcher pattern, Runnable runnable) { 
     this.pattern=pattern; 
     this.runnable=runnable; 
    } 

    public boolean apply(String s) { 
     if (pattern.matcher(s).matches()) { 
      runnable.run(); 
      return true;} 
     } else { 
      return false; 
     } 
    } 
} 

한 다음 사용

for (PatternMatcher matcher: pm) { 
    if (matcher.apply(s)) { 
     break; 
    } 
} 

편집 :

PatternMatcher[] pm = { 
    new PatternMatcher(...), 
    new PatternMatcher(...), 
    ... 
}; 

for (PatternMatcher matcher: pm) { 
    matcher.apply(s); 
} 

를 첫 번째 일치하는 패턴이 발견 된 후 중지하려면,이 루프를 사용하여 보정 변수 이름

관련 문제