2010-11-26 8 views
11

String을 가져 와서 다른 문자 집합과 바꾸는 일종의 파서를 작성해야합니다. 코드는 다음과 같습니다.많은 문자열을 수행하는 가장 빠른 방법은 Java에서 바꿉니다.

noHTMLString = noHTMLString.replaceAll("</p>", "\n"); 
noHTMLString = noHTMLString.replaceAll("<br/>", "\n\n"); 
noHTMLString = noHTMLString.replaceAll("<br />", "\n\n"); 
//here goes A LOT of lines like these ones 

이 함수는 매우 길며 많은 문자열을 대체합니다. 여기서 문제는 응용 프로그램의 성능이 저하되어 많은 시간이 소요되는 메서드이기 때문에 많은 시간이 필요하다는 것입니다. 이 여기 Does string.replaceAll() performance suffer from string immutability? 언급 String 클래스에서 완전히 대체 방법은

일치 패턴 & Matcher를하고 Matcher.replaceAll와 함께 작동됩니다으로

나는 대안으로의 StringBuilder를 사용하는 방법에 대한 몇 가지 스레드를 읽고 있지만 완전히 대체 방법이 부족하고()는 StringBuilder를 사용하여 최종 반환 값 을 저장하므로 StringBuilder로 전환하면 실제로 대체 작업을 수행하는 시간이 단축되는지 알 수 없습니다.

빠른 방법으로 많은 문자열을 빠르게 바꾸는 방법을 알고 계십니까? 이 문제에 대한 조언이 있으십니까?

감사합니다.

EDIT : 일부 필드가 html 텍스트 인 보고서를 만들어야합니다. 각 행에 대해 이러한 문자열 내부의 모든 HTML 태그와 특수 문자를 대체하는 메서드를 호출하고 있습니다. 전체 보고서를 작성하면 모든 텍스트를 구문 분석하는 데 3 분 이상 소요됩니다. 문제는 내가이 메소드를 매우 자주 호출해야한다는 것입니다.

+0

당신의 속도가 느려 집니까? - noHTMLString 텍스트의 길이 또는이 세 문을 매우 자주 호출합니까? – Ralph

+0

html 텍스트가있는 몇 개의 필드가있는 보고서를 만들어야합니다. 각 행에 대해 이러한 문자열 내부의 모든 HTML 태그와 특수 문자를 대체하는 메서드를 호출하고 있습니다. 전체 보고서를 작성하면 모든 텍스트를 구문 분석하는 데 3 분 이상 소요됩니다. 그래서 문제는 제가이 메소드를 매우 자주 호출해야한다는 것입니다. – Averroes

+0

참고 : http://stackoverflow.com/a/1765616/59087 –

답변

12

StringBuffer에 신경 쓰고 싶지 않으면 org.apache.commons.lang.StringUtils가 가장 빠릅니다.

당신은 다음과 같이 사용할 수 있습니다 :
noHTMLString = StringUtils.replace(noHTMLString, "</p>", "\n");

내가 제안 하나 @extraneon와 유사한 내 사용자 지정 StrinBuffer 솔루션보다 더 부패했다 성능 테스트를했다.

+0

실제로 String.class의 replaceAll보다 빠릅니다. 감사. – Averroes

+0

벤치 마크에서 [Commons Lang StringUtils.replace performance vs. String.replace] (http://stackoverflow.com/questions/16228992/commons-lang-stringutils-replace-performance-vs-string-replace)를 참조하십시오. – Vadzim

+0

여러 문자열의 경우 [StringUtils.replaceEach]를 사용하는 것이 더 빠릅니다 (https://commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/apache/commons/lang/StringUtils.html# replaceEach (java.lang.String, % 20java.lang.String [], % 20java.lang.String [])), [parsing HTML] (http://stackoverflow.com/a/1732454/59087)이 아닙니다. 방법은 좋은 생각입니다. –

6

휠을 다시 발명하는 대신을 사용하는 것과 관련하여 HTML을 파싱하는 것처럼 보입니까?

4

나는 Martijn이 직접 파싱하는 대신 준비된 솔루션을 사용하는 것에 동의합니다. javax.xml 패키지에 Java에 내장 된 많은 것들이 있습니다. 깔끔한 해결책은 XSLT 변환을 사용하여 대체하는 것입니다.이 방법은 이상적인 사용 사례처럼 보입니다. 그러나 그것은 복잡합니다.

질문에 대답하려면 regular expression libraries을 사용해 보셨습니까? 당신이 원하는 많은 다른 것들을 가지고 있고, 같은 것 (\ n 또는 빈 문자열)으로 바꾸는 것처럼 보입니다. 정규식을 사용하면 "<br>|<br/>|<br />"과 같은 표현이되거나 <br.*?>"과 같이 더 똑똑한식이 될 수 있으므로 replaceAll을 호출 할 수있는 정규식 객체를 만들 수 있습니다.

+2

HTML을 정규식으로 구문 분석 할 수 없습니다. http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml- 자체 포함 태그 –

+1

Adriaan, 맞습니다. HTML은 일반적인 언어가 아닌 컨텍스트가없는 언어입니다. 하지만 정규 표현식을 사용하여 텍스트를 대체 할 수 있습니다. – Allanrbo

3

전 Martijn과 완전히 동의합니다. 작업에 적합한 도구를 선택하십시오.

그러나 파일이 HTML이 아니며 일부 HTML 토큰 만 포함하는 경우 몇 가지 방법으로 속도를 높일 수 있습니다.

첫째, 입력의 일부 금액이 교체 요소를 포함하지 않는 경우, 같은 것을 시작으로 고려해 패턴을하지 마십시오

Pattern p = Pattern.compile(your_regex); 

: 정규식을 고려

if (!input.contains('<')) { 
    return input; 
} 

두 번째 모든 하나의 replaceAll 라인에 대해,하지만 그들을 결합하려고하면 (정규식은 OR 연산자를 가짐) 패턴이 정규 표현식을 최적화하도록합니다. 패턴을 사용하여 패턴을 사용하고 모든 호출에서 컴파일하지 않아도되므로 상당히 비쌉니다.정규 표현식에 당신은 또한 몇 가지 빠른 (그러나 잠재적으로 덜 읽을 수있는) 대체 엔진 자신을 구현할 수 복잡한 조금 있으면

:

StringBuilder result = new StringBuilder(input.length(); 
for (int i=0; i < input.length(); i++) { 
    char c = input.charAt(i); 

    if (c != '<') { 
    continue; 
    } 

    int closePos = input.indexOf('>', i); 
    if (closePos == -1) {// not found 
    result.append(input.substring(i, input.length()); 
    return result.toString(); 
    } 
    i = closePos; 
    String token = input.substring(i, closePos); 
    if (token.equals("p/") { 
    result.append("\\n"); 
    } else if (token.equals(...)) { 
    } else if (...) { 
    } 
} 
return result.toString(); 

이 몇 가지 오류 :

이있을 수 있습니다 장점은 가지고있다 입력을 한 번만 반복합니다. 큰 단점은 모든 것을 이해하기가 쉽지 않다는 것입니다. 새로운 상태가 무엇인지 문자별로 분석하여 상태 머신을 작성할 수도 있으며, 이는 더 빠르고 더 많은 작업이 될 것입니다.

+1

정규 표현식으로 HTML을 파싱 할 수 없습니다. http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags –

+1

@Adriaan Koster : 그건 제가 말한 것이 아닙니다. HTML을 사용하는 경우 HTML 구문 분석기를 사용해야합니다. HTML 태그가있는 일반 텍스트 (HTML 구문 분석기로 파싱 할 수 없음)는 어려운 방법입니다. – extraneon

+2

@Adriaan : ** WRONG! ** [예, * 정규식을 사용하여 HTML을 파싱 할 수 있습니다] (http://stackoverflow.com/questions/4231382/regular-expression-pattern-not-matching-anywhere-in-string/ 4234491 # 4234491). 그러나, 당신은 [아마도]하고 싶지 않아 (http://stackoverflow.com/questions/4284176/doubt-in-parsing-data-in-perl-where-am-i-going-wrong/4286326#4286326) 자신이 생성 한 HTML과 같이 작동하도록 제한된 HTML을 제한하지 않는 한. 그렇지 않으면 ** 정규 표현식 **으로 HTML을 완전히 파싱 할 수는 있지만 정말로 원하지는 않습니다. – tchrist

관련 문제