Regex match variable identifiers, function identifiers, function parameter and class name from a string

Viewed 49

Hay, i need your help...
So we have an example code at textarea and we will use regex to match all:

  • class name
  • function and variable identifier, and
  • parameter inside parentheses (...)

this is the expected return :

(abc) (a) (abc123) (taHandler) (elem) (pattern) (caret_start) (ClassMates) (name) (age) (displayInfo)

if you want to edit at regex101: https://regex101.com/r/UCI6Np/1

I already do half of work intil i get stuck to matching variable identifiers that separated by coma. I really appreciate any help from you guys. if something is not clear, fell free to ask me at comment section.

const str = document.getElementById('val_').value;
const regex = /(?<=(let|var|const|function|class)\s+)(\w+)/g;
let m;

while ((m = regex.exec(str)) !== null) {
    // avoid infinite loops with zero-width matches
    if (m.index === regex.lastIndex) { regex.lastIndex++; }
    
    // The result can be accessed through the `m`-variable.
    m.forEach((match, groupIndex) => {
       if( groupIndex === 2 ){
         console.log(`match:(${match})`);
       }
    });
}
/* 
we need to match :
- class name
- function and variable identifier
- parameter inside parentheses (...)
this is the expected return :
(abc)
(a)
(abc123)
(taHandler) 
(elem)
(pattern)
(caret_start)
(ClassMates)
(name)
(age)
(displayInfo)
*/

/*
edit on regex101:
https://regex101.com/r/UCI6Np/1
*/
<textarea id="val_" style="width:100%;height:200px;">
this just example code for regex matching purpose:
var abc = 123;
let a = 'ok';
const abc123 = 'yep';
        function taHandler(elem) {
            let
            pattern     = /\r?\n|\r/,
            caret_start = elem.selectionStart,
            caret_end   = elem.selectionEnd,
            elmval_     = elem.value;
class ClassMates{
    constructor(name,age){
        this.name=name;
        this.age=age;
    }
    displayInfo(){
        return this.name + "is " + this.age + " years old!";
    }
}
</textarea>

2 Answers

You almost had it done. One difficulty I found is like you said to match variable identifiers separated by commas.

I think if you check they're preceded by a comma and followed by a = (+ optional white spaces) you'll be quite safe:

(?<=(let|var|const|function|class)\s+)(\w+)|(?<=,\s+)(\w+)(?=\s*=)|(?<=[\(,])(\w+)(?=[\),])|(?<=}\s+)(\w+)(?=\()

In order to recognize functions in a class I check if they are preceded by } and followed by ( (+ optional white spaces). This way we exclude the constructor.

I have used this expression to read cpp source code. this is an expression I used to find function name.

"(?<returnType>(\w+(\[\])|\w+\*|\w+))([\n\r\s])(?<methodName>\w+)\s*\((\s*((?:\s*(?<parameterType>(\w+(\[\])|\w+\*|\w+))\s+(?<parameter>\w+)\s*,?\s*))?)+\)"

Which can detect function name like :

  • int main()
  • int main(int a,int b)
  • int main(int[] a)
  • int main(int* ptr,int a)
  • int* main()
  • void main()
  • int[] main()

And also able to get those name into parameter.

public void evaluate()
    {
        
        foreach (string data in strData.Split('\n'))
        {
            
            MatchCollection matchs = Regex.Matches(data, @"(?<returnType>(\w+(\[\])|\w+\*|\w+))([\n\r\s])(?<methodName>\w+)\s*\((\s*((?:\s*(?<parameterType>(\w+(\[\])|\w+\*|\w+))\s+(?<parameter>\w+)\s*,?\s*))?)+\)");
            foreach (Match match in matchs)
            {
                string returnType = match.Groups["returnType"].Captures[0].Value;
                string methodName = match.Groups["methodName"].Captures[0].Value;
                       
                  
                    var typeParameterPair = new List<KeyValuePair<string, string>>();
                    int i = 0;
                   
                    foreach (var capture in match.Groups["parameterType"].Captures)
                    {
                        typeParameterPair.Add(new KeyValuePair<string,string>(match.Groups["parameterType"].Captures[i].Value, match.Groups["parameter"].Captures[i].Value));
                        i++;
                    }

                FunctionData tempData = new FunctionData();
                tempData.returnType = returnType;
                tempData.methodName = methodName;
                tempData.parameters = typeParameterPair;

                funcData.Add(tempData);
            
            }
        }
    }
Related