This discussion is archived
9 Replies Latest reply: Mar 21, 2007 2:46 PM by 807606 RSS

curious regex + replace problem

807606 Newbie
Currently Being Moderated
i am building a jsp tag which takes a template with some tokens and generates 10 templates with tokens replaced by text of different lengths.

I think what i am doing is becoming too complex and can be done in a better way. here is a small self contained chunk of code that does about the same thing that i do:
     private void blee (){
          String token = "TOKEN";
          String text = "This is some text with a TOKEN. my friend likes to TOKEN his pipe.\n";
          String randomHack = "1234567890";
          Random rand = new Random();
          Pattern p = Pattern.compile(token);
          StringBuffer b = new StringBuffer(text.toString());
          StringBuffer result = new StringBuffer();
          Matcher m = p.matcher(b);
          int count = 0;
          while(count++ < 10){ //create 10 templates worth of stuff
//               do not modify original template
               StringBuffer buff = new StringBuffer(b.toString()); 
               while(m.find()){
                    String replaceTokenWith = randomHack.substring(rand.nextInt(10));
                    buff.replace(m.start(), m.end(), replaceTokenWith); //replace it
               }
               result.append(buff);
               m.reset(); 
          }
          System.out.println(result.toString());
     }
produces this output:
This is some text with a 89. my friend likes to TOK123456789s pipe.
This is some text with a 9. my friend likes to TOKE789 pipe.
This is some text with a 789. my friend likes to TO456789is pipe.
This is some text with a 56789. my friend likes to 0123456789 his pipe.
This is some text with a 3456789. my friend likes t9EN his pipe.
This is some text with a 456789. my friend likes to23456789N his pipe.
This is some text with a 56789. my friend likes to 0123456789 his pipe.
This is some text with a 789. my friend likes to TO0123456789is pipe.
This is some text with a 56789. my friend likes to 0123456789 his pipe.
This is some text with a 89. my friend likes to TOK3456789s pipe.

it seems like im going to keep track of many lengths inside of my code, and it will become ugly.
  • 1. Re: curious regex + replace problem
    807606 Newbie
    Currently Being Moderated
    also, this needs to be fast, its going to be in a custom jsp tag, so no funny business!
  • 2. Re: curious regex + replace problem
    807606 Newbie
    Currently Being Moderated
    ok everyone took too long, here is the solution:
         private void blee (){
              String token = "TOKEN";
              String text = "This is some text with a TOKEN. my friend likes to TOKEN his pipe.\n";
              String randomHack = "1234567890";
              Random rand = new Random();
              Pattern p = Pattern.compile(token);
              StringBuffer b = new StringBuffer(text.toString());
              StringBuffer result = new StringBuffer();
              Matcher m = p.matcher(b);
              int count = 0;
    
              while(count++ < 10){ //create 10 templates worth of stuff
                    while (m.find()) {
                         String replaceTokenWith = randomHack.substring(rand.nextInt(10));
                        m.appendReplacement(result, replaceTokenWith);
                    }
                    m.appendTail(result);
                    m.reset();
                    
              }
              System.out.println(result.toString());
         }
  • 3. Re: curious regex + replace problem
    807606 Newbie
    Currently Being Moderated
    Not bad. One warning, though: appendReplacement() processes the replacement string looking for $n group references, which means it always treats dollar signs and backslashes specially. If the text is randomly generated, or otherwise not known at compile time, you need to disable or bypass that special processing. My favorite way to do that is to pass an empty string to appendReplacement(), then append the replacement string to the StringBuffer using its own append() method (as shown below). Another option is to use the Matcher.quoteReplacement() method that was added in JDK 1.5.

    Here's what I was working on while you were so patiently waiting. ^_^ It's essentially the same as your code, just a slightly more modular approach.
    import java.util.*;
    import java.util.regex.*;
    
    public class Test
    {
      private static String randomHack = "1234567890";
      private static Random rand = new Random();
    
      public static void main(String... args)
      {
        String text = "This is some text with a TOKEN.  My friend likes to TOKEN his pipe.";
        String regex = "TOKEN";
        
        for (int i = 0; i < 10; i++)
        {
          System.out.println(hackIt(text, regex));
        }
      }
      
      private static String hackIt(String text, String regex)
      { 
        Pattern p = Pattern.compile("TOKEN");
        Matcher m = p.matcher(text);
        StringBuffer sb = new StringBuffer();
        while (m.find())
        {
          m.appendReplacement(sb, "");
          sb.append(randomHack.substring(rand.nextInt(10)));
        }
        m.appendTail(sb);
        return sb.toString();
      }
    }
  • 4. Re: curious regex + replace problem
    807606 Newbie
    Currently Being Moderated
    heh,

    thanks for your help, your warning about the $ might have saved me from a bug in production, so you get 9 dukes! i get 1 for doing it faster then you because i get paid for it :P

    i will keep your advice in mind for later
  • 5. Re: curious regex + replace problem
    800241 Newbie
    Currently Being Moderated
    heh,

    thanks for your help, your warning about the $ might
    have saved me from a bug in production, so you get 9
    dukes! i get 1 for doing it faster then you because i
    get paid for it :P
    Faster doesn't always mean better.

    I am the first signature in the give all 10 dukes to your poor old uncle_alice's campaign to platnium drive.
  • 6. Re: curious regex + replace problem
    807606 Newbie
    Currently Being Moderated
    ill give you another duke for your permission to blog this =)

    got a link or something so i can credit you?
  • 7. Re: curious regex + replace problem
    807606 Newbie
    Currently Being Moderated
    Faster doesn't always mean better.
    i hate you
  • 8. Re: curious regex + replace problem
    800241 Newbie
    Currently Being Moderated
    Faster doesn't always mean better.
    i hate you
    Why I thought we could be BFF ??
  • 9. Re: curious regex + replace problem
    807606 Newbie
    Currently Being Moderated
    ill give you another duke for your permission to blog this =)
    At that price, how can I say no? ^_^
    got a link or something so i can credit you?
    Just here, so far. But the siren call of my own blog is becoming increasingly difficult to resist.