Replace java function with regex: matching parentheses

I want to replace function definition and declaration with Regex, i.e.

replace

public abstract void myFuction(MyParam myParam); 

or

 @Override public void myFuction(MyParam myParam){ } 

I tried with this regex:

 (@Override[\n\s\t]*)?public *(abstract)? *void *generateProcessMethod *\(UIGenerationContext *[^)]+\)[\n\\s\t]*((\{[^{}]*?\})|;) 

But the problem is that the function has any other { or } , then it will not work.

Replacing [^{}] with . is not a solution because it also replaces the following functions.

+4
source share
4 answers

Using regular expressions, this (bracketing) can , but only to a fixed level of nesting.

Your current regex (slightly changed):

 (@Override[\n\s\t]*)?public *(abstract)? *void *[az]*\([az]* [^)]+\)[\n\\s\t]*((\{[^\{\}]*?\})|;) 

Only one level. More specifically, this is the part that corresponds to it:

 (\{[^\{\}]*?\}) 

If you want to combine up to two levels, change the specified part to:

 (\{([^{}]*|\{[^{}]*\})*\}) 

In this way:

 (@Override[\n\s\t]*)?public *(abstract)? *void *[az]*\([az]* [^)]+\)[\n\\s\t]*(\{([^{}]*|\{[^{}]*\})*\}|;) 

To add additional levels, you must continue to edit. It will become more messy and messy when you add levels.

Explanation:

  • \{ will match the first open bracket
    • ( opens a group
      • [^{}]* matches anything other than brackets
      • | or
      • \{ if he finds an opening bracket ...
        • [^{}]* ... it will match anything but the parenthesis ...
      • \} ... until it finds a closing bracket
    • ) closes the group
    • * above group may consist of zero or more times
  • \} matches end bracket

To add other levels, change the middle (second) part of [^{}]* to ([^{}]*|\{[^{}]*\})* .

If you cannot predict the maximum level of nesting:

There are several languages ​​that allow the nesting operator R , which allows you to set an arbitrary number of levels. If your language does not support it (Java does not work, PHP and Perl afik), you will have to either:

  • predict the maximum level of nesting; OR
  • create a parser yourself.

Regular expressions without the R operator cannot set any number of levels.

However, using the R operator will be like this:

 (\{([^{}]|(?R))*\}) 

More info on this answer .

+6
source

Regex is not suitable for working with nested components. However, if you know that @Override will @Override same way as the closing bracket, and all its contents will indent further, you can use this:

 ([\t\s]+)@Override.*?\n\1} 
+1
source

Normal regular expressions, as already mentioned, are not able to do what you need.

However, you can use Perl 6, which allows the recursive structure of templates. At one point, the possibility of matching nested brackets was suggested, but Larry Sten rejected the idea. However, he presented a kind of sketch of how recursive matching can be used to achieve essentially the same goal: http://www.perl.com/pub/2002/06/04/apo5.html?page = 24 # rfc 145: bracematching for perl regular expressions

(Honestly, I'm not sure why he didn't just decide to use a simple int-counter for each type of brackets, but ... I'm not Larry Wall.)

+1
source

I am afraid that this is not possible using only RegExpressions.

If you understand correctly that you need to reformat some syntax, and I assume that the code still needs to be compiled, in this case you will need to counteract what increases for each { and decreases for each } so that you know when the function ends. An alternative would be to return to the first one found } after you come across the next declaration, but there would be many exceptions to handle, for example, when the class ends, etc.

I suggest you use Java parsing for this task, it will be able to recognize the method as a method and save you a lot of work, take a look at javaparser , for example

0
source

All Articles