2017-01-18 5 views
0

タグを含む文字列を分割する必要があります。たとえば:タグごとに異なる変数に文字列を分割する

String str = "This text is not highlighted <hlTag>but this is</hlTag> this" 
      + " isn't again <hlTag>and this is</hlTag>"; 

問題は、私のパーサがタグ内であり、これではないどの部分、知っている必要がありますので、すべての部品は、(この例では、私はちょうどそれらをプリントアウト)異なる変数に保存されなければならないということです。

私はすでに解決策を持っていますが、両方のケースで2つの正規表現を使用していますが、単純化することができると思います。

EDITED

私は私の解決策が間違っていることに気づいた - 私は、部品の順序を失うと、私はそれを尊重する必要があります。私は文字列を一度解析し、タグ付きタグのない部分のためにパーツを別のオブジェクトに保存する必要があります(ハイライトされている場合は、list.add(新しいHighlPart(text))。そうでなければlist.add(new NonHighlPart(text))

誰でも助けてくれますか?

String preTag = "<hlTag>"; 
String postTag = "</hlTag>"; 

Matcher insideTagsMatcher = Pattern.compile(preTag + "(.+?)" + postTag).matcher(str); 
Matcher outsideTagsMatcher = Pattern.compile("^(.*?)" + preTag + 
    "|" + postTag + "(.*?)" + preTag + 
    "|" + "</hlTag>(.*?)$").matcher(str); 

System.out.println("Highlighted:"); 
while (insideTagsMatcher.find()) { 
    System.out.println(insideTagsMatcher.group(1)); 
} 

System.out.println("\nNot highlighted:"); 
while (outsideTagsMatcher.find()) { 
    for (int i = 1; i <= outsideTagsMatcher.groupCount(); i++) { 
     // each pattern group returns two nulls except of string we need 
     if (outsideTagsMatcher.group(i) != null) 
      System.out.println(outsideTagsMatcher.group(i)); 
    } 
} 

結果は次のとおりです。

 
Highlighted: 
but this is 
and this is 

Not highlighted: 
This text is not highlighted 
this isn't again 
+1

非常に単純な構文を除いて、Regexは厄介なパーサーです。実際のパーサーを使用してください。 – Andreas

答えて

1

クリーンで安全な方法を使用Jsoupだろう。

import org.jsoup.Jsoup; 
import org.jsoup.nodes.Document; 
import org.jsoup.nodes.TextNode; 
import java.util.List; 
import java.util.stream.Collectors; 

public class Test { 
public static void main(String[] args) { 
    Document document = Jsoup.parse("This text is not highlighted <hlTag>but this is</hlTag> this isn't again <hlTag>and this is</hlTag>"); 

    List<String> highlighted = document.select("hlTag") 
      .stream() 
      .map(element -> element.html()) 
      .collect(Collectors.toList()); 

    List<String> nonHighlighted = document.body().childNodes().stream() 
      .filter(node -> node instanceof TextNode) 
      .map(node -> node.toString().replaceAll("\n","")) 
      .collect(Collectors.toList()); 

    highlighted.forEach(System.out::println); 
    nonHighlighted.forEach(System.out::println); 
} 
} 

出力:

but this is 
and this is 
This text is not highlighted 
this isn't again 

が問題になっている変更後を更新:

List挿入要素の順序を保ちます。異なるタイプのオブジェクトをリストに追加することはできません。あなたの新しいニーズを正しく理解していれば、次のようなことができます:

List<Node> nodes = document.body().childNodes(); 
nodes.forEach(System.out::println); 

nodesはNode要素のリストです。各ノード(この例では)は、TextNodeまたはElementのタイプにすることができます。あなたの例では、TextNodeはbodyから解析されたときにタグにラップされていないコンテンツに対応し、Elementオブジェクトはタグを持つコンテンツに対応します。このようにして、すべてのエレメントを持つユニークなリストが作成されます。オブジェクトタイプ(instanceof)を使用すると、それらの間で異なることがあります。

ハイライト部分を印刷しますか?次に:

nodes.stream().filter(node -> node instanceof TextNode).forEach(System.out::println); 

ハイライトされていない部分を印刷したいですか?次に:

nodes.stream().filter(node -> node instanceof Element).forEach(System.out::println); 
+0

ありがとうございます!もう1つの質問 - 部品の順序を保存して1つのリストに保存できますか?つまり、タグ付きタグと非タグ付きパーツのオブジェクトが異なる場合は、一度解析してこのようなことを行うことができます(ハイライトされている場合は、 ?更新されたレスポンスの場合は –

+0

、問題を解決する場合はレスポンスを受け入れることを忘れないでください。 – exoddus

関連する問題