I have lots of code blocks like:
try
{
...
}
catch(Exception123 &e)
{
...
}
I want to replace them with something like this:
MY_MACRO(try
{
...
})
catch(Exception123 &e)
{
...
}
Exception123 is key, only blocks catching that specific type should be identified. But the exception caught might not always be called e or exist at all. And the precise structure and formatting of the code-block isn't always the same... we might have try {.
Is it feasible to use regex in a Visual-Studio find-replace for this? I couldn't figure out how I would group/identify the main try block.
Ok. Sorry, I havn't saw the second part of your question :
I think there is the regex you want for search :
(try[\r\n]+{[^\}]+[\r\n]+)(})([\r\n]+catch\(Exception123)
And in replacement field :
MY_MACRO($1$2)$3
Related
I've got a Node module file containing about 100 exported methods, which looks something like this:
exports.methodOne = async user_id => {
// other method contents
};
exports.methodTwo = async user_id => {
// other method contents
fooMethod();
};
exports.methodThree = async user_id => {
// other method contents
fooMethod();
};
Goal: What I'd like to do is figure out how to grab the name of any method which contains a call to fooMethod, and return the correct method names: methodTwo and methodThree. I wrote a regex which gets kinda close:
exports\.(\w+).*(\n.*?){1,}fooMethod
Problem: using my example code from above, though, it would effectively match methodOne and methodThree because it finds the first instance of export and then the first instance of fooMethod and goes on from there. Here's a regex101 example.
I suspect I could make use of lookaheads or lookbehinds, but I have little experience with those parts of regex, so any guidance would be much appreciated!
Edit: Turns out regex is poorly-suited for this type of task. #ctcherry advised using a parser, and using that as a springboard, I was able to learn about Abstract Syntax Trees (ASTs) and the recast tool which lets you traverse the tree after using various tools (acorn and others) to parse your code into tree form.
With these tools in hand, I successfully built a script to parse and traverse my node app's files, and was able to find all methods containing fooMethod as intended.
Regex isn't the best tool to tackle all the parts of this problem, ideally we could rely on something higher level, a parser.
One way to do this is to let the javascript parse itself during load and execution. If your node module doesn't include anything that would execute on its own (or at least anything that would conflict with the below), you can put this at the bottom of your module, and then run the module with node mod.js.
console.log(Object.keys(exports).filter(fn => exports[fn].toString().includes("fooMethod(")));
(In the comments below it is revealed that the above isn't possible.)
Another option would be to use a library like https://github.com/acornjs/acorn (there are other options) to write some other javascript that parses your original target javascript, then you would have a tree structure you could use to perform your matching and eventually return the function names you are after. I'm not an expert in that library so unfortunately I don't have sample code for you.
This regex matches (only) the method names that contain a call to fooMethod();
(?<=exports\.)\w+(?=[^{]+\{[^}]+fooMethod\(\)[^}]+};)
See live demo.
Assuming that all methods have their body enclosed within { and }, I would make an approach to get to the final regex like this:
First, find a regex to get the individual methods. This can be done using this regex:
exports\.(\w+)(\s|.)*?\{(\s|.)*?\}
Next, we are interested in those methods that have fooMethod in them before they close. So, look for } or fooMethod.*}, in that order. So, let us name the group searching for fooMethod as FOO and the name of the method calling it as METH. When we iterate the matches, if group FOO is present in a match, we will use the corresponding METH group, else we will reject it.
exports\.(?<METH>\w+)(\s|.)*?\{(\s|.)*?(\}|(?<FOO>fooMethod)(\s|.)*?\})
Explanation:
exports\.(?<METH>\w+): Till the method name (you have already covered this)
(\s|.)*?\{(\s|.)*?: Some code before { and after, non-greedy so that the subsequent group is given preference
(\}|(?<FOO>fooMethod)(\s|.)*?\}): This has 2 parts:
\}: Match the method close delimiter, OR
(?<FOO>fooMethod)(\s|.)*?\}): The call to fooMethod followed by optional code and method close delimiter.
Here's a JavaScript code that demostrates this:
let p = /exports\.(?<METH>\w+)(\s|.)*?\{(\s|.)*?(\}|(?<FOO>fooMethod)(\s|.)*?\})/g
let input = `exports.methodOne = async user_id => {
// other method contents
};
exports.methodTwo = async user_id => {
// other method contents
fooMethod();
};
exports.methodThree = async user_id => {
// other method contents
fooMethod();
};';`
let match = p.exec( input );
while( match !== null) {
if( match.groups.FOO !== undefined ) console.log( match.groups.METH );
match = p.exec( input )
}
I have custom code for opening db connection and closing it. I need to find the methods where the close connection did not happen. I am looking for regEx which can give the places where this does not occur.
Update: The getConnection and closeconnection are defined in a single class and referred in multiple classes and multiple methods of same class. There are nesting of the multiple try-with-resources or regular try blocks(but without getconnection ) or other for/if blocks as well.
e.g.
public void method(){
try{
Connection conn= getConnection();
}
catch(){}
finally{
closeConnection();
}
}
This will find occurrence of getConnection() without occurrence of closeConnection() in one file.
"getConnection\(\);((?!closeConnection\(\);).)+$"gs
Demo: https://regex101.com/r/Rygoq5/1
It assumes one file has only one connection. It will fail if one file has two function that both has getConnection() string.
Given that the OP requested a Regex for Eclipse, this one will find try-catch blocks containg getConnection pattern but not closeConnection
(?m)try(.|\n)+getConnection(.|\n)+catch(.|\n)+(?<!\n\s+closeConnection[ ^}]+\n)[}]\n\s*\n
Matches
try {
// Connection conn = getConnection();
} catch (Exception e) {
} finally {
}
}
Also matches
try {
//Connection conn = getConnection();
} catch (Exception e) {
}
}
Used with Search file utility as
If "Look-behind group does not have an obvious maximum length near index " error appears, try
(?m)try(.|\n)+getConnection(.|\n)+catch(.|\n)+(?<!\n\s{1,100}closeConnection[^ }]{1,1000}\n)[}]\n\s*\n
Assuming there are no nested {...} blocks, the regular expression to find the cases where closeConnection is missing is:
\btry\s*+\{[^\}]*\bgetConnection\b[^\}]*\}(?!\s*(catch\b[^\{]*\{[^\}]*\}\s*)?finally\b[^\{]*\{[^\}]*\bcloseConnection\b[^\}]*}\s*)
To look for getConnection not followed by closeConnection (not at all or not before the next getConnection, in case for files with multiple getConnections) use the following:
\bgetConnection\b(?!((?!\bgetConnection\b)[\s\S])*\bcloseConnection\b)
I need a custom validator to ban a specific list of banned words from a textarea field.
I need exactly this type of implementation, I know that it's not logically correct to let the user type part of a query but it's exactly what I need.
I tried with a regExp but it has a strange behaviour.
My RegExp
/(drop|update|truncate|delete|;|alter|insert)+./gi
my Validator
export function forbiddenWordsValidator(sqlRe: RegExp): ValidatorFn {
return (control: AbstractControl): { [key: string]: any } | null => {
const forbidden = sqlRe.test(control.value);
return forbidden ? { forbiddenSql: { value: control.value } } : null;
};
}
my formControl:
whereCondition: new FormControl("", [
Validators.required,
forbiddenWordsValidator(this.BAN_SQL_KEYWORDS)...
It works only in certain cases and I don't understand why does the same string works one time and doesn't work if i delete a char and rewrite it or sometimes if i type a whitespace the validator returns ok.
There are several issues here:
The global g modifier leads to unexpected alternated results when used in RegExp#test and similar methods that move the regex index after a valid match, it must be removed
. at the end requires any 1 char other than line break char, hence it must be removed.
Use
/drop|update|truncate|delete|;|alter|insert/i
Or, to match the words as whole words use
/\b(?:drop|update|truncate|delete|alter|insert)\b|;/i
This way, insert in insertion and drop in dropout won't get "caught" (=matched).
See the regex demo.
it's not a great idea to give such power to the user
Is it possible to use the flowVariable inside wildcard or expression filter directly.
I need to stop the flow based on the flow Variable value.
Example: My flow Variable name keyValue have the value like customer/feed/h26/h56 in this 'h26/h56' should set dynamically but customer/feed is constant always. I need to set my filter only after '/feed/' if it contain any characters.
<flow name="testFlow1" doc:name="testFlow1">
<file:inbound-endpoint responseTimeout="10000" doc:name="File" path="c:/in"/>
.......( Many component)
<set-variable variableName="keyValue" value="#[customer/feed/h26/h56]" doc:name="Variable"/>
.......( Many component)
<message-filter doc:name="Message">
<wildcard-filter pattern="customer/feed/+*" caseSensitive="true"/>
</message-filter>
</flow>
Used + in pattern to check whether it contain one or more characters.
Also I used expression filter, not sure how to use flow Variable inside the filter expression. Could you please help me on this.
I don't want to use property filter.
Use expression filter instead, and since your expression is simple just use the startsWith method of String.
for example
<expression-filter expression="flowVars.keyValue.startsWith('customer/feed/')" doc:name="Expression"/>
this will allow messages
First of all, you can't use wildcard-filter on flowVars directly because it applies a wildcard pattern to the message payload. Here is the implementation excerpt from the org.mule.routing.filters.WildcardFilter class
public boolean accept(MuleMessage message) {
try {
return accept(message.getPayloadAsString());
} catch (Exception e) {
logger.warn("An exception occurred while filtering", e);
return false;
}
}
So it is clear that the WildcardFilter converts the payload to a String and applies the filter.
Also, in the case of regex-filter, it applies a regex pattern to the message payload. Here is an implementation excerpt from the org.mule.routing.filters.RegExFilter
public boolean accept(MuleMessage message) {
try {
return accept(message.getPayloadAsString());
} catch (Exception e) {
throw new IllegalArgumentException(e);
}
}
Now coming to your question, you can very well use expression-filter as suggested by Tyrone Villaluna. But you may want to include the expression in start and end signs like ^customer/feed/.+$
And so
<expression-filter expression="flowVars.keyValue.matches('^customer/feed/.+$')" />
I am looking for the regex which will let me use search replace to add 2 lines of code to all java methods in file using Notepad++
Before:
public void startProcessing() {
..............
..............
}
After:
public void startProcessing() {
logger.info( "Entering into startProcessing" );
..............
..............
logger.info( "Exiting startProcessing" );
}
Is this possible, if yes can anyone help me with the code... or guide me on any other possible way to do this.
To start with the "bad news", you won't be able to insert the "Exiting" line unless you have a much-better fingerprint to match against. With your current code-sample, the best you can match against is } and, as a wild guess, there are probably a lot of closing-curly-brackets throughout your code.
To insert the "Starting" line is do-able, but the robustness depends on your input.
If you will always want to replace the same line as in your sample code (or the same format but different function name), you could do the following in the Find+Replace menu:
Find:
public void startProcessing() {
Replace:
public void startProcessing() {\n\tlogger.info("Entering into startProcessing");
Search Mode: Extended
If you want to dynamically do the replacement with a non-hardcoded function name, you could try the following:
Find:
(public void )([a-zA-Z0-9_$]+)(.*)
Replace:
\1\2\3\n\tlogger.info\("Entering into \2"\);
Search Mode: Regular Expression
This "dynamic" method will require whatever methods you're searching for the be declared in the same format though, public void functionName.... I've used [a-zA-Z0-9_$] as the character-set for the function names, but you can adjust this to suit your needs.
UPDATE (ignore get/set methods)
To ignore get/set methods, such as getFieldValueUnits() or setFieldValueUnits(int val), you can use the following Find value (the Replace is the same-as-above):
(public void )(?!get|set)([a-zA-Z0-9_$]+)(.*)
This will match all functions that do not start with get or set (and are declared as public void, as above).