挑选一个字符串并替换它

时间:2012-09-20 18:39:24

标签: 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 : _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("\"");

但我真的只需要一些关于如何做到这一点的想法。

3 个答案:

答案 0 :(得分: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”}}],这里还有一些文字,还有一些“ - > [{}]部分应该用它们里面的文本替换,在这种情况下设置,书籍,etbo ...导致最后的字符串“你好我的名字是等等,等等,设置书籍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,这里有更多文字,还有更多

答案 1 :(得分: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

答案 2 :(得分: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()之后重置匹配器,但我认为它在这里是安全的,因为它将在替换之后继续,这正是我们想要的。

我想指出,这特别有效。我认为你最好手动做更多的事情而不是正则表达式。