- Come up with a good REGular EXspresion (REGEX), for matching your desired code.
- Come up with your replacement regex and capture user.
- Ensure that your code compiles and inspect your changes.
In this case we want to replace the following:
package com.ecokrypt... public class ToManySystemOuts { System.out.println("Single Line System.out.println"); System.out.println("Rare multiline " + " System.out.println "); }We need to find a REGEX that will match both of these cases. There are several ways to do any REGEX, but a solution that is easy to understand that will work is:
(?s)System.out.println(\(([^;]+?)\));
We have to dissect what this is saying to understand a couple of subtleties:
- (?s) - indicates that we search past line feeds. Without this we will not match the second case because the line feed would cause the REGEX to not match at all.
- System.out.println - matches the exact phrase
- (\(([^;]+?)\)) - is very complicated, and will take time before you can read this. A technique that typically works is to read it inside out. Trying that out:
- [^;]+ - look for anything that is NOT a ';' (semicolon). the + is saying that you have to match at least 1, and there is no limit to how many characters you can match.
- ([^;]+?) - Has a real subtlety to it, Regexes have an ability to be greedy, or lazy. A greedy regex will match the largest region it can. A lazy regex will match the smallest area it can. It will take time to figure out when to use which, but the basic advice given here is ALWAYS try to use lazy. Only use greedy if you really need it. This REGEX is obviously lazy, how can you tell? Think about it a bit.
- the ? indicates that you are going to look for the next sequence imediately after.
- the (...) indicates you are going to "capture" whatever you find presumably for later use.
- therefore the ( ) are not matched but are just part of the regex capture syntax.
- So the answer is: if the ? is inside the capture group e.g. (...?) the matching is lazy; if the ? is outside of the capture group, the matching is greedy e.g. (...)?
- \(([^;]+?)\) - says, adds the \(...\) to the previous the \ is an escape character and says match a ( and a ), don't create another capture group.
- (\(...\)) - says, now add another capture group containing everything inside the literals ( ).
- ; the semicolon at the end says match a literal semicolon.
That is pretty much all there is to it. Look at the following REGEX, which might be a common mistake and see if you can figure out why it won't work. Guess what it will match. (HINT thing about greedy vs lazy).
(?s)System.out.println(\(([^;]+)?\));
Now that we have our matching REGEX, we need to get our replacement REGEX:
System.out.println$1;
This is much simpler, it says: replace the above match, with logger.debug$1; where $1 is inclusive the literal (...). e.g. the braces and everything inside of them.
How do we do this inside of Eclipse or NetBeans?
I find NetBeans to be much nicer in some respects, and not so nice in others.
NetBeans in File Search Replace |
NetBeans Replace Across All Files USE CRTL-H for a shortcut to this Menu. |
NetBeans Confirmation Dialog |
Eclipse:
The Eclipse Search Dialog. (Allows you to select scope) |
No comments:
Post a Comment
All comments are greatly appreciated! Comments will be moderated, and usually appear within 1 day. If you like a post, instead of saying you like it, vote for it or digg it (links provided). If there is any ERROR, PLEASE Comment I strive for good quality complete content.