惟有于技术中才能明得真相

简易正则表达式测试工具

Firefox有个正则表达式测试扩展,叫做Regular Expressions Test,其功能很简单。个人觉得要是为了测试正则表达式,完全没必要使用这个扩展,写几行JavaScript代码即可搞定。我要完成的任务很简单,就是给定一个正则表达式和一个字符串,找出字符串中所有匹配正则表达式的子串。下面是它的一个初步实现:

function regmatch(regex, text) {
    regex.lastIndex = 0;
    var result = [];
    var m;
    while ((m = regex.exec(text)) != null) {
            result.push(m[0]);
            if (!regex.global) break;
    }
    return result;
}


将它输入到Firebug控制台中测试:


>>> regmatch(/[Hh]ello/g, "Hello, hello")
["Hello", "hello"]


通常我们要对同一个正则表达式使用多个测试字符串,regmatch要求多次重复传递这个正则表达式。我们可以通过让regmatch返回一个函数,然后多次调用这个函数对字符串进行测试。对代码作如下改动:

function regmatch(regex, text) {
    if (!text) {
        return function(t) {
            regex.lastIndex = 0;
            var result = [];
            var m;
            while ((m = regex.exec(t)) != null) {
                result.push(m[0]);
                if (!regex.global) break;
            }
            return result;
        }
    } else {
        return regmatch(regex)(text);
    }
}


它首先判断text是否为空,为空
(即只有一个参数)则返回一个测试函数,它接受一个字符串作为参数,这利用了JavaScript的闭包特性。如果text非空,则返回匹配的子串,在实现上使用了一点技巧,它首先调用regmatch(regex)返回测试函数(因为text为空),然后再调用这个函数来返回匹配的子串。在Firebug控制台中测试:


>>> var m = regmatch(/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?/g);
>>> m("div > p")
["div", ">", "p"]
>>> m("div,p")
["div,", "p"]

例子中的正则表达式来源于jQuery中chunk正则表达式,它用于把CSS选择器切分成多个部分,把它传递给regmatch并调用,返回函数为m,然后多次调用函数m来对不同字符串进行匹配,并返回匹配结果。

这样我就完成了一个简单的正则表达式测试工具,它的功能很简单,却相当实用。要完成其它更复杂的功能(如replace,sub group等),就需要改代码了,好在并不复杂。

0 评论: