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然后只用这些单词替换原始找到的模式。如果字符串包含"通过,我可以搜索它

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... 导致最终字符串“你好,我的名字是,等等,等等,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);

输出:

你好,我的名字是,等等,等等,set set Books 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

好的,我认为您需要分三遍执行此操作,第一次匹配 之间的部分[{ }],第二次通过匹配进行替换,第三次将匹配替换为您从第二遍获得的字符串。

您已经有了第一次匹配的模式,当您用第二次传递的结果替换它时,您只需再次将其用于第三次匹配。

对于第二次传球,您将需要replaceAll在第一场比赛中进行。像这样的东西:

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

第一遍由 完成matcher.find()。下一个由 完成matcher.group().replaceAll(),然后传递到matcher.replaceFirst()第三遍。第三遍有点奇怪:它替换了[{ }]. 但是,由于我们从头开始并继续前进,那将是我们刚刚找到的那个,我们不会再次匹配它,因为它将被不匹配的字符串替换。文档建议在 之后重置匹配器replaceFirst(),但我认为它在这里是安全的,因为它会在替换之后继续,这正是我们想要的。

我要指出,这并不是特别有效。我认为您最好手动执行更多操作而不是使用正则表达式。

于 2012-09-20T19:13:42.507 回答