Home > database >  Creating a specific regex
Creating a specific regex

Time:05-23

I am trying to create a regex in Code::Blocks to find all occurrences of when a function is called with a specific parameter.

The function is called:

int mdw_button(int x1, int y1, int x2, int y2, int bn, ....

and I want to find occurrences of when the 5th parameter is a specific value...

So basically

  • start with mdw_button(
  • then skip past 4 occurrences of numbers or letters ended with a comma
  • then match on the fifth..

OK I have been asked for a minimum working example:

  • In Code::Blocks open the 'Find in Files' dialog with CTRL-SHIFT-F

  • Check 'Look in all project files'

  • Check 'Regular Expression'

  • In the "Text to search for" field I have tried:

    mdw_button(.*15

Gets a lot of results...basically anything that starts with: mdw_button( and has a 15 anywhere later on the line. This works but has a lot of false positives.

mdw_button(.*[,] 15 This works and I get a shorter list, but still lots of false positives

So many things I have tried give me absolutely no results at all:

mdw_button(.*[,] 15

mdw_button( ([A-Za-z0-9]{1}[,])4 15

I want something that will match the pattern of: [any text or number followed by a comma]

Then I want to skip past 4 of those and match whatever is next

here is some examples of code I am looking through:

mdw_button(xa, ya, xb, ya bts-2, 26, num, type, obt, 0,  15,  13, 14, 1,0,0,d); ya =bts; // stat | fall | carry
mdw_button(xa, ya, xb, ya bts-2, 49, num, type, obt, 0, 12 ,  15,  0, 1,0,0,d); ya =bts; // door type
mdw_button(xa, ya, xb, ya bts-2, 4,  num, type, obt, 0, abc, atc,  0, 1,0,0,d); ya =bts; // set linked item
mdw_button(xa, ya, xb, ya bts-2, 50, num, type, obt, 0, abc, atc,  0, 1,0,0,d); ya =bts; // enter mode (up | down)
mdw_button(xa, ya, xb, ya bts-2, 53, num, type, obt, 0, abc, atc,  0, 1,0,0,d); ya =bts; // move type
mdw_button(xa, ya, xb, ya bts-2, 51, num, type, obt, 0, abc, atc,  0, 1,0,0,d); ya =bts; // exit link show
mdw_button(xa, ya, xb, ya bts-2, 52, num, type, obt, 0,  13,  15,  0, 1,0,0,d); ya =bts; // get new shape
mdw_colsel(xa, ya, xb, ya bts-2, 5,  num, type, obt, 0,   0,   0,  0, 0,0,0,d); ya =bts; // change color

CodePudding user response:

You can try with this:

mdw_button\((?:\s*[\w -] ,){4}\s*50,

The specific fifth parameters value is "50" in this example. It will match only the part up to and including that fifth parameter.If you want to match the whole call, you should add a .*?;. It will still just match the call and not the whole line.

You were starting off correctly. but:

  • to match a literal ( you have to escape it as \(
  • if you want to count the first four parameters, you should group them with a non-capturing group like this: (?:\s*[\w -] ,)
  • this group starts with an optional amount of whitespace: \s*, followed by minimum 1 or more word characters (\w) or or - - to support more operations or spaces in the parameters, you will have to extend this!
  • inside the group also the final , is important
  • you want to occur the group exactly 4 times: {4}
  • again an optional amount of whitespace is following
  • then the parameter you search for is following
  • end with a comma to prevent that the results only match the start of the parameter you look for.

Please keep in mind that you can't build a full expression parser with regex, so if you have parenthesis or more complex expressions as parameters, you probably are better off with a regular parser.

CodePudding user response:

Not a regex, but a way to filter your data using awk.

Lets say your input data is in file data.txt.

You could do:

awk 'BEGIN { FS = ", " } /^mdw_button/ { if ($5 == "4") print }' data.txt
  • BEGIN { FS = ", " }: set the field separator to , and
  • /^mdw_button/: line starts with "mdw_button"
  • if the 5th field == "4", print that line.

With your example data, the result is:

mdw_button(xa, ya, xb, ya bts-2, 4,  num, type, obt, 0, abc, atc,  0, 1,0,0,d); ya =bts; // set linked item
  • Related