unwitting
unwitting

Reputation: 3396

Replacement String Conditional on Match

I would like to know if it's possible in most regex search-and-replace mechanisms to conditionally replace with a literal string based on whether a certain match has occurred. My working example is this pair of regex replaces:

^(\s*([\S]*):.*function.*\((.+)\).*\{.*)$ -> \1 console.info('\2 ::: \3:', \3); ^(\s*([\S]*):.*function.*\(\).*\{.*)$ -> \1 console.info('\2');

The first replaces lines such as:

test: function (arg1, arg2) {
    //pass
}

with:

test: function (arg1, arg2) { console.info('test2 ::: arg1, arg2:', arg1, arg2);
    //pass
}

and the second one does the same for functions with no arguments like:

test2: function () {
    //pass
}

I'm looking for a way to apply only a single search-and-replace to perform both of these tasks. One way, if this is possible, would be to essentially say "if I have \3, replace ::: \3:', \3, else don't. Is this possible? Is there another way?

Upvotes: 1

Views: 1515

Answers (1)

Regular Jo
Regular Jo

Reputation: 5510

You can do something like this

var code = document.getElementById("code");
code.value = code.value.replace(/\b(function\s*(?:[\w.]+)?)\s+\((.*?)\)\s*{/g,function(match,p1,p2) {
    if (p2.length) {
        return match + "console.info('test2 ::: arg1, arg2:', p1, p2);"
    } else {
        return match + "console.info('other contents');"
    }
})

If your arguments are simple values*, you can do something like this

var code = document.getElementById("code");
code.value = code.value.replace(/\b(function\s*(?:[\w.]+)?)\s+\((.*?)\)\s*{/g,function(match,p1,p2) {
    if (p2.length) {
        var ParamsCount = p2.split(",").length;
        var ParamString = []
        for (p=0;p<ParamsCount;p++) {
            ParamString[p] = "'Arg" + p + ": ' + " + "arguments[" + p +"]"
        }
        return match + "console.log(" + ParamString.join(", ") + ")"
    } else {
        return match + "console.info('other contents');"
    }
})
  • Because it does a rudimentary split based on a comma, arguments with nested commas would cause problems.. like function foo(bar(1,2),"sample") { or function foo("hey, that's cool") would each screw up the arguments.

Regex Explanation

`\b`                    # Token: \b (word boundary)
`(`                     # Opens CG1
    `function`          # Literal function
    `\s*`               # Token: \s (white space)
                          # * repeats zero or more times
    `(?:`               # Opens NCG
        `[\w.]+`        # Character class (any of the characters within)
                          # Token: \w (any alpha or numeric character)
                          # Any of: .
                          # + repeats one or more times
    `)?`                # Closes NCG
                          # ? repeats zero or one times
`)`                     # Closes CG1
`\s+`                   # Token: \s (white space)
                          # + repeats one or more times
`\(`                    # Literal (
`(`                     # Opens CG2
    `.*?`               # . denotes any single character, except for newline
                          # * repeats zero or more times
                          # ? as few times as possible
`)`                     # Closes CG2
`\)`                    # Literal )
`\s*`                   # Token: \s (white space)
                          # * repeats zero or more times
`{`                     # Literal {

JSFiddle (demo of both, just uncomment the single commented return): http://jsfiddle.net/rg23LL0p/

Upvotes: 1

Related Questions