2

私は最近頭を悩ませていますが、この文字列から「テキスト」を引き出して、見つかったパターンをそれらの単語に置き換える方法がわからないようです。

Pattern searchPattern = Pattern.compile("\\[\\{(.+?)\\}\\]"); 
Matcher matcher = searchPattern.matcher(sb);

sbで始まり、[{で終わるこれらのパターンのいくつかのオカレンスを含む文字列です]}

[{ md : {o : "set", et : _LU.et.v.v }, d : {t : _LU.el.searchtype, l : _LU[_LU.el.searchtype].nfts.l, v : _LU[_LU.el.searchtype].nfts.v}}, { md : {o : "set", et : _LU.et.v.v }, d : {t : _LU.el.topicgroup, l : "Books", v : "ETBO"}}]

として返されます

md : {o : "set", et : _LU.et.v.v }, d : {t : _LU.el.searchtype, l : _LU[_LU.el.searchtype].nfts.l, v : _LU[_LU.el.searchtype].nfts.v}}, { md : {o : "set", et : _LU.et.v.v }, d : {t : _LU.el.topicgroup, l : "Books", v : "ETBO"}

[{との欠如に注意してください}]。私はなんとか上記のパターンを見つけることができましたが、どのようにして単語を見つけてsetBook元の見つかったパターンをそれらの単語だけに置き換えるのでしょうか。"文字列にviaが含まれている場合は検索できます

while (matcher.find()) {
        matcher.group(1).contains("\"");

しかし、私は本当にこれを行う方法についていくつかのアイデアが必要です。

4

3 に答える 3

2

これはあなたが探しているものですか(最初のコメントに基づいて答えてください)?

実際にはかなり大きいですが、「こんにちは、私の名前は、などなどです。[{md:{o: "set"、et:_LU.et.vv}、d:{t:_LU .el.searchtype、l:_LU [_LU.el.searchtype] .nfts.l、v:_LU [_LU.el.searchtype] .nfts.v}}、{md:{o: "set"、et:_LU .et.vv}、d:{t:_LU.el.topicgroup、l: "Books"、v: "ETBO"}}]、ここにもう少しテキスト、そしてもう少し"->[{}]の部分はこの場合、set、books、etbo ...の内部のテキストに置き換えられ、「hello my name is、etc、etc、etc、set set Books ETBO、ここにさらにいくつかのテキスト、その他いくつかのテキストが追加されます。 「」

// text from your comment
String sb = "hello my name is, etc, etc, etc, [{ md : "
        + "{o : \"set\", et : _LU.et.v.v }, d : {t : "
        + "_LU.el.searchtype, l : _LU[_LU.el.searchtype].nfts.l, "
        + "v : _LU[_LU.el.searchtype].nfts.v}}, { md : {o : "
        + "\"set\", et : _LU.et.v.v }, d : {t : _LU.el.topicgroup, "
        + "l : \"Books\", v : \"ETBO\"}}] , "
        + "some more text here, and some more";

Pattern searchPattern = Pattern.compile("\\[\\{(.+?)\\}\\]");
Matcher matcher = searchPattern.matcher(sb);

// pattern that finds words between quotes
Pattern serchWordsInQuores = Pattern.compile("\"(.+?)\"");

// here I will collect words in quotes placed in [{ and }] and separate 
// them with one space
StringBuilder words = new StringBuilder();

// buffer used while replacing [{ xxx }] part with words found in xxx
StringBuffer output = new StringBuffer();

while (matcher.find()) {// looking for [{ xxx }]
    words.delete(0, words.length());

    //now I search for words in quotes from [{ xxx }]
    Matcher m = serchWordsInQuores.matcher(matcher.group());
    while (m.find())
        words.append(m.group(1)).append(" ");

    matcher.appendReplacement(output, words.toString().trim());
    //trim was used to remove last space
}
//we also need to append last part of String that wasn't used in matcher
matcher.appendTail(output);

System.out.println(output);

出力:

こんにちは私の名前は、などなど、セットブックETBO、ここにいくつかのテキスト、そしていくつかの

于 2012-09-20T19:44:19.717 に答える
1

最新の改訂

複数の境界を持つ文字列をループし、各レベルで置き換える方法の例

public static String replace(CharSequence rawText, String oldWord, String newWord, String regex) {
    Pattern patt = Pattern.compile(regex);
    Matcher m = patt.matcher(rawText);
    StringBuffer sb = new StringBuffer(rawText.length());
    while (m.find()) {

        String text = m.group(1);
        if(oldWord == null || oldWord.isEmpty()) {
            m.appendReplacement(sb, Matcher.quoteReplacement(newWord));
        } else {
            if(text.matches(oldWord)) {
                m.appendReplacement(sb, Matcher.quoteReplacement(newWord));
            }
        }
    }
    m.appendTail(sb);
    return sb.toString();
}

public static void main(String[] args) throws Exception {
    String rawText = "[{MY NAME IS \"NAME\"}]";
    rawText += " bla bla bla [{I LIVE IN \"SOME RANDOM CITY\" WHERE THE PIZZA IS GREAT!}]";
    rawText += " bla bla etc etc [{I LOVE \"A HOBBY\"}]";
    System.out.println(rawText);
    Pattern searchPattern = Pattern.compile("\\[\\{(.+?)\\}\\]");
    Matcher matcherBoundary = searchPattern.matcher(rawText);

    List<String> replacement = new ArrayList<String>();
    replacement.add("BOB");
    replacement.add("LOS ANGELES");
    replacement.add("PUPPIES");
    int counter = 0;

    while (matcherBoundary.find()) {

        String result = Test.replace(matcherBoundary.group(1), null, replacement.get(counter), "\"([^\"]*)\"");
        System.out.println(result);
        counter++;
    }
}

私が得る出力は次のとおりです。

**Raw Text**
[{MY NAME IS "NAME"}] bla bla bla [{I LIVE IN "SOME RANDOM CITY" WHERE THE PIZZA IS GREAT!}] bla bla etc etc [{I LOVE "A HOBBY"}]
**In Every Loop**
MY NAME IS BOB
I LIVE IN LOS ANGELES WHERE THE PIZZA IS GREAT!
I LOVE PUPPIES
于 2012-09-20T19:05:06.363 に答える
1

OK、これは3つのパスで行う必要があると思います。最初は、の間のセクションを一致させ[{ }]、2回目は置換を実行して一致させ、3回目はその一致を2回目のパスから取得した文字列に置き換えます。

すでに最初の試合のパターンがあり、それを2番目のパスの結果に置き換えるときに、3番目の試合で再び使用します。

replaceAll2回目のパスでは、最初の試合で行う必要があります。このようなもの:

Pattern searchPattern = Pattern.compile("\\[\\{(.+?)\\}\\]"); 
Matcher matcher = searchPattern.matcher(sb);
while ( matcher.find() )
{
    matcher.replaceFirst(matcher.group(1).replaceAll("[^\"]*\"([^\"]*)\"", "$1"));
}

最初のパスはによって行われmatcher.find()ます。次のパスmatcher.group().replaceAll()はによって実行され、3番目のパスに渡されmatcher.replaceFirst()ます。3番目のパスは少し奇妙です:それはの最初の例を置き換えます[{ }]。ただし、最初から始めて前進しているので、それが今見つけたものになり、一致しない文字列に置き換えられるため、再度一致することはありません。ドキュメントでは、後でマッチャーをリセットすることを推奨していますが、交換後も継続するため、ここでは安全replaceFirst()だと思います。これはまさに私たちが望んでいることです。

これは特に効率的ではないことを指摘しておきます。正規表現を使用するよりも、これを手動で行う方がよいと思います。

于 2012-09-20T19:13:42.507 に答える