Java 拆开一根绳子并把它放回原处

Java 拆开一根绳子并把它放回原处,java,regex,Java,Regex,我最近一直在思考,似乎不知道如何从这个字符串中提取文本,并用这些单词替换找到的模式 Pattern searchPattern = Pattern.compile("\\[\\{(.+?)\\}\\]"); Matcher matcher = searchPattern.matcher(sb); sb是一个字符串,其中包含一些以[{开头并以]}结尾的模式 返回为 md : {o : "set", et : _LU.et.v.v }, d : {t : _LU.el.searchtype, l

我最近一直在思考,似乎不知道如何从这个字符串中提取文本,并用这些单词替换找到的模式

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"}
注意缺少[{和}]。我设法找到了上面的模式,但是如何找到单词set和Book,然后用这些单词替换原来找到的模式呢。如果字符串包含via,我可以搜索该字符串

但我真的需要一些关于如何做这件事的想法

最新版本

关于如何在具有多个边界的字符串上循环并在每个级别替换的示例

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++;
    }
}
最新版本

关于如何在具有多个边界的字符串上循环并在每个级别替换的示例

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++;
    }
}

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

您已经有了第一个匹配的模式,当您用第二次传递的结果替换它时,您只需在第三个匹配中再次使用它

对于第二次传球,你需要在第一场比赛中替换所有球员。大概是这样的:

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。第三个过程有点奇怪:它替换了[{}]的第一个示例。但是,由于我们从头开始并向前推进,这将是我们刚刚找到的,我们不会再次匹配它,因为它将被一个不匹配的字符串替换。文档建议在更换后首先重置匹配器,但我认为这将是安全的,因为它将在更换后继续,这正是我们想要的


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

好的,我认为您需要分三次执行此操作,第一次匹配[{}]之间的节,第二次执行替换,第三次用第二次传球时得到的字符串替换匹配

您已经有了第一个匹配的模式,当您用第二次传递的结果替换它时,您只需在第三个匹配中再次使用它

对于第二次传球,你需要在第一场比赛中替换所有球员。大概是这样的:

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。第三个过程有点奇怪:它替换了[{}]的第一个示例。但是,由于我们从头开始并向前推进,这将是我们刚刚找到的,我们不会再次匹配它,因为它将被一个不匹配的字符串替换。文档建议在更换后首先重置匹配器,但我认为这将是安全的,因为它将在更换后继续,这正是我们想要的


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

根据您的第一条评论,这就是您想要的答案吗


它实际上相当大。。我的名字是,等等,等等,[{md:{o:set,et:{u-LU.et.v.v},d:{t:{u-LU.el.searchtype,l:{u-LU[\u-LU.el.searchtype].nfts.l,v:{u-LU[\u-LU.el.searchtype].nfts.v},{md o:set,et:{u-LU et.v.v},d:{t:{u-LU el.el.topicgroup,l:Books,v:ETBO},还有更多的文本,这里有[}]在本例中,零件应替换为其内部的文本集、书籍等。。。最后一个字符串是hello,我的名字是,等等,等等,等等,set Books,ETBO,这里还有一些文本,还有一些

输出:

你好,我的名字是,等等,等等,等等,集书,这里有更多的文字,还有更多


根据你的第一条评论,这就是你想要的答案吗


它实际上相当大。。我的名字是,等等,等等,[{md:{o:set,et:{u-LU.et.v.v},d:{t:{u-LU.el.searchtype,l:{u-LU[\u-LU.el.searchtype].nfts.l,v:{u-LU[\u-LU.el.searchtype].nfts.v},{md o:set,et:{u-LU et.v.v},d:{t:{u-LU el.el.topicgroup,l:Books,v:ETBO},还有更多的文本,这里有[}]在本例中,零件应替换为其内部的文本集、书籍等。。。最后一个字符串是hello,我的名字是,等等,等等,等等,set Books,ETBO,这里还有一些文本,还有一些

输出:

你好,我的名字是,等等,等等,等等,集书,这里有更多的文字,还有 更多


好吧,我很困惑。能否显示示例字符串的前后版本?它实际上相当大。。我的名字是,等等,等等,[{md:{o:set,et:{u-LU.et.v.v},d:{t:{u-LU.el.searchtype,l:{u-LU[\u-LU.el.searchtype].nfts.l,v:{u-LU[\u-LU.el.searchtype].nfts.v},{md o:set,et:{u-LU et.v.v},d:{t:{u-LU el.el.topicgroup,l:Books,v:ETBO},还有更多的文本,这里有[}]在本例中,零件应替换为其内部的文本集、书籍等。。。最后一个字符串是hello my name is,etc,etc,etc,etc,set Books,ETBO,这里还有更多的文本,等等。你不能仅仅使用string.replaceAll来删除所有出现的[{和}]?replaceAll不适用,因为这个数据是动态的,因为我从文件中提取它,并在打算解析它之前清理它。我正在用itOK内部的一些位替换找到的模式,我非常困惑。能否显示示例字符串的前后版本?它实际上相当大。。我的名字是,等等,等等,[{md:{o:set,et:{u-LU.et.v.v},d:{t:{u-LU.el.searchtype,l:{u-LU[\u-LU.el.searchtype].nfts.l,v:{u-LU[\u-LU.el.searchtype].nfts.v},{md o:set,et:{u-LU et.v.v},d:{t:{u-LU el.el.topicgroup,l:Books,v:ETBO},还有更多的文本,这里有[}]在本例中,零件应替换为其内部的文本集、书籍等。。。最后一个字符串是hello my name is,etc,etc,etc,etc,set Books,ETBO,这里还有更多的文本,等等。你不能仅仅使用string.replaceAll来删除所有出现的[{和}]?replaceAll不适用,因为这个数据是动态的,因为我从文件中提取它,并在打算解析它之前清理它。我正在用iTunes内部的一些位替换找到的模式,我的理解是sb不是那个字符串,而是一个更大的字符串,它在[{}]中包含该格式的多个部分,因此在从中获取引号之前,您必须找到各个[{}]部分。此外,我没有看到任何迹象表明\w+是合适的-你需要匹配引号之间的任何内容,无论是一个词还是多个词,或者只是胡言乱语。\[^\]*\会比\\w+\好吗?我个人使用\[^\]*\因为我认为他不想保留引号,但是的。我就是这样做的,但如果它必须被引用呢?我更希望它们不被引用,但这不是什么大不了的事。@KRyan假设是正确的,sb是一个非常非常大的字符串,这是它的一个子字符串。[{}]中的部分也不知道。可以保证的是[{}]中的引号中有一些单词不幸的是,我的理解是,sb不是那个字符串,而是一个更大的字符串,它包含[{}]中该格式的多个部分,因此在从中获取引号之前,您必须找到各个[{}]部分。此外,我没有看到任何迹象表明\w+是合适的-你需要匹配引号之间的任何内容,无论是一个词还是多个词,或者只是胡言乱语。\[^\]*\会比\\w+\好吗?我个人使用\[^\]*\因为我认为他不想保留引号,但是的。我就是这样做的,但如果它必须被引用呢?我更希望它们不被引用,但这不是什么大不了的事。@KRyan假设是正确的,sb是一个非常非常大的字符串,这是它的一个子字符串。[{}]中的部分也不知道。可以保证的是[{}]中的引号中有一些单词,这似乎是无限期地停留在这个时候loop@wazy:能否尝试添加matcher.reset;在循环中的第一行被替换之后?这似乎被无限期地卡住了loop@wazy:能否尝试添加matcher.reset;在循环中的第一行之后?
Pattern searchPattern = Pattern.compile("\\[\\{(.+?)\\}\\]"); 
Matcher matcher = searchPattern.matcher(sb);
while ( matcher.find() )
{
    matcher.replaceFirst(matcher.group(1).replaceAll("[^\"]*\"([^\"]*)\"", "$1"));
}
// 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);