2016-09-21 5 views
1

태그 -> HTML 파서 - 사용자 정의 태그 (BB와 Markdown 사이의 뭔가, 예 : [b] 또는 [#RRGGBB])를 사용자가 입력하면 HTML로 구문 분석되므로 [#FF0000]red text[/#]<span style='color:#FF0000;'>red text</strong>으로 바뀌고 HTML이있는 JTextPane에 배치됩니다. 스타일.

모든 사용자 태그 및 HTML 매장의 HashMap과 같은 구문 분석 :

public static String parseBBToHTML(String text) { 
    String html = text; 

    Map<String,String> bbMap = new HashMap<String , String>(); 

    bbMap.put("\\[b\\]", "<strong>"); 
    bbMap.put("\\[/b\\]", "</strong>"); 
    ... 
    bbMap.put("\\[color=(.+?)\\]", "<span style='color:$1;'>"); 
    bbMap.put("\\[/color\\]", "</span>"); 

    for (Map.Entry entry: bbMap.entrySet()) { 
     html = html.replaceAll(entry.getKey().toString(), entry.getValue().toString()); 
    } 

    return html; 
} 

그리고 반환 단지 다른 후 하나의 문자를 입력 한 내용을 다른 방법으로 애니메이션 효과와 함께 JTextPane의에서 .setText()에 사용되는 값 그들 사이에 일시 중지합니다.

모두 잘 작동하지만, 지금은 한 가지 생각하고 있어요 :이 같은 빈 HTML 태그와 애니메이션을 입력에서 일시 정지를 모방하고있어

: "!"<!!!!!!!!!!>

그래서 10 그들 사이의 20ms에서 일시 중지와 함께 나에게 200ms의 일시 정지를 준다. 나는이 방법으로 "태그를 일시 정지"고 형성하고있어 (그 인수는 INT했지만, 지금은 문자열을 사용하는 이유는, 볼) :

public static String pause(String ms){ 
    String pausedText = ""; 
    int time = Integer.parseInt(ms); 
    for (int i = 0; i < (time/animationSpeed); i++) { 
     pausedText = pausedText + "!"; 
    }  
    return "<"+pausedText+">"; 
} 

나는 2000ms에 일시 정지에 대한 [!2000] 같은 태그를 사용합니다. 그래서 저는 다음과 같이 파서 문자열을 넣었습니다 :

bbMap.put("\\[\\!(.+?)\\]", Dialogue.pause("$1")); 

... 작동하지 않았습니다. Dialogue.pause 문자 그대로 문자열 인 "$ 1"을 제공하며, 구문 분석의 가치는 $1이 아닙니다.

$1을 인수로 사용하여 "일시 중지 태그"를 만들고이를 텍스트에 넣을 수 있습니까?

+0

무슨 이득이 클래스 : Dialogue.pause –

+0

일시 정지 경우'entry.getValue의 toString()()'수익을 무엇을.? – Thomas

+0

Dialogue.pause는 내 게시물에 있습니다. ** public static String pause (String ms) ** 등등. – Lemis

답변

1

문자열은 하나의 정적 값입니다. 원하는 것은 다른 String으로부터 동적으로 계산되는 String입니다.

당신이에서지도를 변경해야

Map<String, String> bbMap = new HashMap<String, String>(); 

이에 :

Map<String, UnaryOperator<String>> bbMap = new HashMap<>(); 

UnaryOperator<String>는 문자열 인수를 받아 문자열 값을 반환하는 함수입니다. 그래서,이 같은지도를 채우는 것 :

bbMap.put("\\[b\\]", s -> "<strong>"); 
bbMap.put("\\[/b\\]", s -> "</strong>"); 
//... 
bbMap.put("\\[color=(.+?)\\]", s -> "<span style='color:" + s + ";'>"); 
bbMap.put("\\[/color\\]", s -> "</span>"); 

bbMap.put("\\[\\!(.+?)\\]", s -> Dialogue.pause(s)); 

for (Map.Entry entry : bbMap.entrySet()) { 
    StringBuffer buffer = new StringBuffer(html.length()); 

    Matcher matcher = 
     Pattern.compile(entry.getKey().toString()).matcher(html); 
    while (matcher.find()) { 
     String match = 
      (matcher.groupCount() > 0 ? matcher.group(1) : null); 
     String replacement = entry.getValue().apply(match); 
     matcher.appendReplacement(buffer, 
      Matcher.quoteReplacement(replacement)); 
    } 
    matcher.appendTail(buffer); 

    html = buffer.toString(); 
} 
+0

와우, 멋지다! UnaryOperator로지도에 대해 들어 본 적이 없어! 하지만 컴파일되지 않습니다. 'apply (String)는 Object 유형에 대해 정의되지 않았습니다. ' 'String replacement = ((Function ) entry.getValue()). apply (match);' 생각하기에, 좋은 것. – Lemis

0

Java $ 1에서는 캡처 명령 외부에 특별한 의미가 없으므로 전역 변수가 아닙니다. 나중에 문자열을 구문 분석하고 그룹을 로컬 변수로 캡처하여 사용해야합니다. Java Regex Replace with Capturing Group

이 이러한 교체에 대한 bbMap 늘 '작업과 현재의 접근 방식을 의미한다

여기를 보라.

이렇게 할 수 있습니다. 먼저 bbMap 수정을 실행하십시오. 그런 다음 bbMap2의 두 번째 수정 세트를 실행하십시오. 먼저 그룹을 캡처하고, 길이를 계산하고, 길이에 따라 원하는 문자열을 작성한 다음 교체하십시오. 내가 다른 코드 bbMap.put("\\[\\!(.+?)\\]", Dialogue.pause("$1"));를 호출하여 틀리지 않는 경우

+0

하지만 어떻게'parseBBToHTML'을 수정할 수 있습니까? 벡터주세요. – Lemis

+0

이 더 많은 설명으로 업데이트되었습니다. –

0

는이 같은 성취하고자 :

  • 는 정규식 그룹에 대한 1
  • Dialogue.pause을 일치하는 항목을 찾으면을 ("$ 1") 그룹 1 (숫자 여야 함)의 내용으로 호출됩니다.

문제는 코드가 리팩터링 될 수 있으므로 문제가되지 않는다는 것입니다. 가능한 태그 (즉, bbMap의 항목)를 반복하고 입력에서 찾고자하는 대신 입력을 반복하고 시작 및 종료 태그를 가져 와서지도에서 조회를 수행 할 수 있습니다.

당신은 정규식에 있음을 그러나 이것은 HTML과 같은 문제를 앓고 있음을 유의하시기 바랍니다 수 있습니다 : 그것은 맞는 정규식을하지 당신이 정말로 데이터 그래서 당신이 할 수 있습니다 무엇인지 등

을 구성하는 방법을 알지 못한다면 표현식을 사용하여 모든 태그를 찾은 다음 태그 이름/내용을 가져온 다음 바꾸기를 수행하십시오. 그러면 다음과 같이 보일 수 있습니다.

Pattern tagPattern = Pattern.compile("\\[(/?)([^\\]]*)\\]"); 
Matcher tagMatcher = tagPattern.matcher(input);  

StringBuffer output = new StringBuffer(); 
while(tagMatcher.find()) { 
    String closeMarker = tagMatcher.group(1); 
    String tagContent = tagMatcher.group(2); 

    //use the tagContent to do the lookup in the map and create the replacement string 
    String replacement = ...; 

    tagMatcher.appendReplacement(output, replacement); 
} 
tagMatcher.appendTail(output); 
+0

저는 입력 텍스트를 한 번만 작성하므로'[! @ # $ arrrawet] '같은 오류가 없습니다. 예, 'get user text -> find tags -> HTML 태그로 바꿀 것'과 같은 코드 구조가 내 parseBBToHTML에 넣고 최상의 결과를 얻는 것보다 낫다. 잠시 후에 다시 시도해 보겠습니다. – Lemis