Hasan A Yousef Hasan A Yousef - 24 days ago 11
C# Question

Converting a JavaScript code using callbacks and RegEx method to equivalent code in C#

I've the below JavaScript code, that returned a function callback related to the user command, the user command could be used in different ways, hence RegEx is required:

(function (undefined) {
"use strict";

var root = this;
var commandsList = [];
var debugStyle = 'font-weight: bold; color: #00f;';

// The command matching code is a modified version of Backbone.Router by Jeremy Ashkenas, under the MIT license.
var optionalParam = /\s*\((.*?)\)\s*/g;
var optionalRegex = /(\(\?:[^)]+\))\?/g;
var namedParam = /(\(\?)?:\w+/g;
var splatParam = /\*\w+/g;
var escapeRegExp = /[\-{}\[\]+?.,\\\^$|#]/g;
var commandToRegExp = function(command) {
command = command.replace(escapeRegExp, '\\$&')
.replace(optionalParam, '(?:$1)?')
.replace(namedParam, function(match, optional) {
return optional ? match : '([^\\s]+)';
})
.replace(splatParam, '(.*?)')
.replace(optionalRegex, '\\s*$1?\\s*');
return new RegExp('^' + command + '$', 'i');
};

var registerCommand = function(command, cb, phrase) {
commandsList.push({ command: command, callback: cb, originalPhrase: phrase });
root.console.log('Command successfully loaded: %c'+phrase, debugStyle);
};

root.fonixListen = {
addCommands: function(commands) {
var cb;
for (var phrase in commands) {
if (commands.hasOwnProperty(phrase)) {
cb = root[commands[phrase]] || commands[phrase];
if (typeof cb === 'function') {
// convert command to regex then register the command
registerCommand(commandToRegExp(phrase), cb, phrase);
} else if (typeof cb === 'object' && cb.regexp instanceof RegExp) {
// register the command
registerCommand(new RegExp(cb.regexp.source, 'i'), cb.callback, phrase);
}
}
}
},
executeCommand: function(commandText) {
for (var j = 0, l = commandsList.length; j < l; j++) {
var result = commandsList[j].command.exec(commandText);
if (result) {
var parameters = result.slice(1);
// execute the matched command
commandsList[j].callback.apply(this, parameters);
return true;
}
}
}
};
}).call(this)


Below are some commands:

var commands = {
'hello :name *term': function(name) {
alert('hello '+name+''); // i.e. consider *term as optional input
},

'items identification': {
'regexp': /^(What is|What's|Could you please tell me|Could you please give me) the meaning of (TF|FFS|SF|SHF|FF|Tube Film|Shrink Film|Stretch Hood|Stretch Hood Film|Flat Film)$/,
'callback': itemsIdentification,
},

'ML SoH': {
'regexp': /^(What is|What's|Could you please tell me|Could you please give me) the (stock|inventory) of ML$/,
'callback': mlSOH,
},

'Report stock on hand': {
'regexp': /^(What is|What's) (our|the) (stock|inventory|SoH) of (TF|FFS|SF|SHF|FF|Tube Film|Shrink Film|Stretch Hood|Stretch Hood Film|Flat Film)$/,
'callback': SoH,
},

'Basic Mathematical Opertions': {
// ?\s? can be used instead of space, also could use /i instead of $/,
'regexp': /^(What is|What's|Calculate|How much is) ([\w.]+) (\+|and|plus|\-|less|minus|\*|\x|by|multiplied by|\/|over|divided by) ([\w.]+)$/,
'callback': math,
},
};


At running the app, the
addCommands
command is executed, and based on the input command from the user, the
executeCommand
command is executed.

The above works very fine with me, but I'm moving to C#, and very new to it, so looking for help, at least guiding of some functionalities and tools in C# that can help me write something similar to the above.

UPDATE
More details about what I try to do, actually I've a form, where the user input his command by voice using HTL5 voice API, the API convert this voice into text, then this text i submitted to my app, where my app work start by looking into this text, trying to find the required command using the ReqEx, then execute the programmed function/callback that is mapped with this input command.

Answer

I found the solution using Dictionary at using System.Collections.Generic; and using RegEx at using System.Text.RegularExpressions; along with the need of a function called FirstOrDefault availabe at using System.Linq;

I used Action instead of function Func as the callbacks in my case are do not return anything, i.e. they are a void functions, and because no input parameters provided, I used Action-delegate, and did not use Action<string[]>.

The working code is:

using System;
using System.Collections.Generic;  // for Dictionary
using System.Linq;  // for FirstOrDefault
using System.Text.RegularExpressions;  // for RegEx

namespace ConsoleApplication
{
    public class Program
    {
        public static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");

            var input = "What's the meaning of Stretch Hood";

                    var functions = new Dictionary<Regex, Action>
                    {
                        {new Regex("/^(What is|What's|Could you please tell me|Could you please give me) the meaning of (TF|FFS|SF|SHF|FF|Tube Film|Shrink Film|Stretch Hood|Stretch Hood Film|Flat Film)$/"),
                             itemsIdentification},
                        {new Regex("/^(What is|What's|Could you please tell me|Could you please give me) the (stock|inventory) of ML$/"),
                             mlSOH},
                        {new Regex("/^(What is|What's) (our|the) (stock|inventory|SoH) of (TF|FFS|SF|SHF|FF|Tube Film|Shrink Film|Stretch Hood|Stretch Hood Film|Flat Film)$/"),
                             SoH},
                        {new Regex("/^(What is|What's|Calculate|How much is) ([\w.]+) (\+|and|plus|\-|less|minus|\*|\x|by|multiplied by|\/|over|divided by) ([\w.]+)$/"),
                             math},
                    };
            functions.FirstOrDefault(f => f.Key.IsMatch(input)).Value?.Invoke();    // This will execute the first Action found wherever the input matching the RegEx, the ?. means if not null ([Null-conditional Operators][1])
// or 
            Action action;
            action = functions.FirstOrDefault(f => f.Key.IsMatch(input)).Value;
            if (action != null)
            {
                action.Invoke();
            }
            else
            {
                // No function with that name
            }
        }

        public static void itemsIdentification()
        {
        Console.WriteLine("Fn 1");
        }

        public static void mlSOH()
        {
        Console.WriteLine("Fn 2");
        }
        public static void SoH()
        {

        }
        public static void math()
        {

        }
    }
}
Comments