2010-06-27 4 views
6

정규식을 사용하여 입력란에 입력 할 때 사용자가 적용한 형식을 결정하려고합니다.Java에서 이러한 정규 표현식이 왜 천천히 실행됩니까?

(\\s?[" + alphabet + "]{9,9})+ 

입력이 소정의 문자 길이 (9)의 하나 이상의 문자열, 공백으로 분리 가능 여부를 확인하기 위해 다음과 같이
정규식이다.

(>[\\w\\s]+\\n[" + alphabet + "\\s]+)+ 

는 입력이 FASTA format

에있는 경우 inputString.matches(regexString)와 일치 할 때 정규 표현식은 대단히 느린 실행 확인하십시오. 왜 이런거야?

이것은 잠재적 인 모든 일치 항목 (이 시점에서 필자는 필요 없음)을 저장했기 때문에 발생할 수 있다고 생각했지만 모든 괄호에 ?:을 추가하면 정규식이 손상됩니다. 어떻게해야합니까? 나는이 문제를 재현 할 수 없습니다 - 그것은 단지 하나의 컴퓨터에서 발생 :

마틴

편집 일을 주셔서 감사합니다. 이것은 특정 VM 설정에 잘못된 점을 제시 할 수 있습니다.
우리는 더 강력한 무엇인가가 필요합니다. 그래서 우리는 이것을 다르게 구현할 것입니다. 필자는 Joel의 답을 올바른 것으로 택했습니다. 왜냐하면 Pattern의 특별한 경우가 원인 일 수 있다고 생각하기 때문입니다.

+0

각 입력 문자열과 일치시킬 패턴은 몇 개입니까? 패턴이 동적 또는 정적입니까? –

+0

@Joel이 두 패턴 만 있습니다. 그들은 정적입니다. String.matches를 사용하면 매번 컴파일이되지만, 패턴과의 일치조차도 한 번에 매우 오래 걸립니다 (약 300 자 입력에 대해 10 초 초과) –

+0

"매우 느립니다"를 정의 할 수 있습니까? –

답변

0

입력을 분류하기 위해 동일한 입력에 대해 일치하는 여러 정규식 패턴이있는 경우 JFlex과 같은 어휘 분석기 생성기를 사용하는 것이 더 나을 것입니다.

일반적으로 컴파일러 생성에 사용되는 기타 Java 기반 어휘 분석기 및 구문 분석 도구는 here으로 나열됩니다.

+0

이들은 유용한 도구입니다. 하지만 난 단지 2 regexes, 그리고 이것은 매우 간단해야합니다 - 나는 JFlex 등을 사용하여 과잉 될 것이라고 생각합니다. –

+0

@Martin -이 경우 JFlex 등이 일반적으로 필요한 것 이상일 것입니다. 그러나 사용중인 정규 표현식을 더 자세히 살펴보면 Pattern 클래스가 분석기를 컴파일하는 방식에있어 일부 사례가 퇴화 될 가능성이 있습니다. JFlex가이 시나리오에 대해 더 강력한 분석기를 생성 할 수 있는지 확인하는 것이 가치가 있습니다. –

1

string.matches() 당신이 할 때마다 정규식을 컴파일하십시오. 대신 미리 컴파일 된 정규식을 캐시 할 수있는 Pattern/Matcher 클래스를 살펴보십시오.

또 다른 것은 일치하는 결과가 필요하지 않으면 비 캡처 정규 표현식 그룹을 사용하는 것입니다.

+0

matches()를 한 번만 호출하므로 문제가되지 않습니다. 정규 표현식은 작은 입력에서는 성능이 뛰어나지 만, 200 문자 이상의 입력으로는 끔찍하게 느리게 수행됩니다. 비 캡처 그룹이 작동하지 못했습니다. 예를 들려 줄 수 있습니까? –

+0

비 포획 그룹으로 전환해도 1000 배 개선되지 않습니다. 그래도 여는 방법은 다음과 같습니다 - 여는 괄호 뒤에 - 예 : (? : \\ s? [ "+ alphabet +"] {9,9}) + – ddimitrov

1

이것은 사용자의 특정 문제를 설명하지 못할 수 있습니다. 하지만 일단 JDK의 정규식 구현으로 뛰어 들었을 때 나는 놀라움을 금치 못했다 입니다. 각 입력 문자에서 진보하는 상태 머신을 실제로 구축하지는 않습니다. 나는 그들이 그들의 이유가 있다고 가정한다.

귀하의 경우, 손으로 직접 구문 분석을 작성하는 것은 매우 쉽습니다. 사람들은 그렇게하기를 두려워하고, 이러한 작은 단계들을 수작업으로 코딩하는 것이 "멍청한"것처럼 보이고, 사람들은 기존의 도서관이 가정에서 성장한 솔루션을 능가하기 위해 훌륭한 트릭을 수행하고 있어야한다고 생각합니다. 그건 사실이 아니야. 많은 경우에 우리의 요구는 비교적 단순하며 DIY보다 더 간단하고 빠릅니다.

+0

Pattern.compile() 메소드는 Pattern.Node 클래스의 자손의 상태 시스템을 빌드합니다. DFA가 아닌 NFA 자동화를 구축한다는 의미입니까? 이것은 대부분의 기능이 풍부한 정규 표현 엔진에서 사용되는 디자인으로 기능에 대한 거래 속도입니다. 다음은이를 설명하고 대안을 제안하는 기사입니다. http://weblogs.java.net/blog/2006/03/27/faster-java-regex-package – ddimitrov