1

I was learning the regex part of Java recently , and today I met a problem about the use of boundry \\G , Here is my code :

  String input = "abcdec";
  System.out.println(String.format("Before :'%s' ; after replace : '%s'", input , input.replaceAll("\\Gx?", "!")));

while it print Before :'abcdec' ; after replace : '!abcdec' , I don't know why it print this , after its first match with the beginning of the string , it replace the place with a char '!' , but then why can't it match again?I think the Regex Expression '\Gx?' could match every place.

I need your help , each help is appreciated!Thanks..

ohyeahchenzai
  • 314
  • 3
  • 13
  • I've searched a bit and found the correct term: *zero-length match* [[1](http://docs.oracle.com/javase/tutorial/essential/regex/quant.html), [2](http://www.regexguru.com/2008/04/watch-out-for-zero-length-matches/)] – Bergi Jul 26 '12 at 08:33
  • related, but without \G: [Java regex anomaly?](http://stackoverflow.com/q/8604286/1048572), [Strange behavior in regexes](http://stackoverflow.com/q/9228509/1048572) and [Zero-length matches in Java Regex](http://stackoverflow.com/q/9906471/1048572) – Bergi Jul 26 '12 at 08:35
  • @Bergi Thank you, but as you say , these doesn't contains '\\G'.But thank you again. – ohyeahchenzai Jul 26 '12 at 08:49

2 Answers2

0

I quote from here: If you wish one search to pick up where the last one left off you can use the "\G" pattern element. This means that if no search has been performed, then \G simply tells the search to start from the beginning of the string and stop on the first match.

Here is another example. Note that again an exclamation mark is added to the begging of the string as the first replace did not move the starting position from 0.

What were you expecting from your program?

Ivaylo Strandjev
  • 69,226
  • 18
  • 123
  • 176
  • I just want to test the function of '\\G' , I meet this problem in the book<> , and I can't understand it.What I can't understand is that after the first replace , why does it stop , I think it should replace again and again , this should be a infinite loop. – ohyeahchenzai Jul 26 '12 at 07:45
  • I believe they have considered the case when your pattern can be of length 0 separately. In that case replace all would result in infinite loop and therefor only the first ocurance(beginning of the string) is replaced – Ivaylo Strandjev Jul 26 '12 at 07:48
  • It may be !I am confused with this, but I can't find it out! – ohyeahchenzai Jul 26 '12 at 08:10
  • What are you trying to find out? Are you expecting the program to go into infinite loop and consume all the memory of your machine? – Ivaylo Strandjev Jul 26 '12 at 08:18
  • No , I am not sure with my assumption , so I need your help with it in order to make sure it ! – ohyeahchenzai Jul 26 '12 at 08:24
0

EDIT: OK, got it. Removed wrong assumptions.


What happens is:

  1. replaceAll starts at the beginning of the input (index 0)
  2. \G matches the initial start value 0
  3. x could not be found - that's OK, it's conditional
  4. the end is reached. Successfull first match from 0 to 0!
  5. Add the replacement ! to the output
  6. Next iteration, starting at one character further (index 1)
  7. The end of the last match was 0. \G, applied on position 1, does not match it!
  8. ...stepping through the whole string, it will never match.
  9. return the output string: !abc...

It got clearer to me when I read the last example from the Regex Boundary Matchers Java Tuturial.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • But according to the book <> , it I use regex 'x?' , it would also result in a infinite loop , but it would result with '!a!b!c!d!e!c!'. – ohyeahchenzai Jul 26 '12 at 07:54
  • Did that book include the Java snippet, or just the regex? – Bergi Jul 26 '12 at 08:00
  • But according to the book , '\\G' in perl has the same meaning in java! – ohyeahchenzai Jul 26 '12 at 08:03
  • I don't think this is a question of the regex syntax, rather one of the method that applies the expression. Perl replace might increment the start index automatically or something... Have you tried the Perl snippet? – Bergi Jul 26 '12 at 08:06
  • I am not familiar with perl , but the result of the '\\G' regex in perl is '!abcdec' , same with Java. – ohyeahchenzai Jul 26 '12 at 08:09