字符串相等测试中的通配符

时间:2014-04-15 06:37:30

标签: javascript regex wildcard equality

如何将字符串与模板匹配,模板使用星号(*)来指定通配符?

通配符应该匹配任意数量的字符,但也应该是可以逃避的(\*不应该被检测为通配符)

例如,我应该使用通配符函数wildCompare(string, template)获取这些结果(仅作为示例)

t = "*have some bacon"
wildCompare("Here, have some bacon", t) // true
wildCompare("Can I have some bacon please", t) // false
wildCompare("have some bacon", t) // true
t = "* \*LOL\* *"
wildCompare("*LOL*", t) // false
wildCompare("Haha *LOL* .", t) // true
t = "hello"
wildCompare("Hi, hello", t) // false
wildCompare("hello, hi", t) // false
wildCompare("hello", t) // true
t = "j*t";
wildCompare("javascript", t) // true
wildCompare("jscript", t) // true
wildCompare("Javascript", t) // false
wildCompare("just out", t) // true
wildCompare("just out here", t) // false

我对正则表达式不是很有信心,但我可以想象某种类型的代码循环遍历字符串中的字符以查看它是否是通配符可行,但是,我不完全确定这是怎么回事实施以上述方式工作。

testing the two answers below之后,Cerbrus创建的indexOf方法似乎是最快的,但是,他的实现不支持转义通配符。

2 个答案:

答案 0 :(得分:2)

如果你忽略了逃避通配符的需要,那么这样的工作就可以了:

t = "I*have some bacon"
function wildCompare(string, search){
    var prevIndex = -1,
        array = search.split('*'), // Split the search string up in sections.
        result = true;
    for(var i = 0; i < array.length && result; i++){ // For each search section
        var index = string.indexOf(array[i]); // Find the location of the current search section
        if(index == -1 || index < prevIndex){ // If the section isn't found, or it's placed before the previous section...
            return false;
        }
    }
    return result;
}

结果:

wildCompare("Here, have some bacon", t) // False
wildCompare("I would like to have some bacon please", t) // True
wildCompare("I have some bacon", t)) // True

解决“通配符转义”问题的最简单方法是使通配符成为可变字符:

function wildCompare(string, search, wildcard){
    var prevIndex = -1,
        sa = search.split(wildcard),
        // Etc

这样,您可以指定通配符是什么,从而提供更大的灵活性。


声明:
我确信这个代码不是“好”,“有效”或类似的东西有很多原因,但它是一种可行的方式。此外,在某些情况下,它可能会返回不正确的值。


mrfishie修复了mutliple顺序通配符的函数:

function wildCompareNew(string, search) {
    var startIndex = 0, array = search.split('*');
    for (var i = 0; i < array.length; i++) {
        var index = string.indexOf(array[i], startIndex);
        if (index == -1) return false;
        else startIndex = index;
    }
    return true;
}

<强> Fiddle

答案 1 :(得分:1)

只要包含preg_quote from PHPJS(替换不应被正则表达式替换的字符,例如.),就可以使用正则表达式在一行中执行此操作。 会忽略您的转义字符。

function preg_quote(str, delimiter) {
  //  discuss at: http://phpjs.org/functions/preg_quote/
  // original by: booeyOH
  // improved by: Ates Goral (http://magnetiq.com)
  // improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  // improved by: Brett Zamir (http://brett-zamir.me)
  // bugfixed by: Onno Marsman
  //   example 1: preg_quote("$40");
  //   returns 1: '\\$40'
  //   example 2: preg_quote("*RRRING* Hello?");
  //   returns 2: '\\*RRRING\\* Hello\\?'
  //   example 3: preg_quote("\\.+*?[^]$(){}=!<>|:");
  //   returns 3: '\\\\\\.\\+\\*\\?\\[\\^\\]\\$\\(\\)\\{\\}\\=\\!\\<\\>\\|\\:'

  return String(str)
    .replace(new RegExp('[.\\\\+*?\\[\\^\\]$(){}=!<>|:\\' + (delimiter || '') + '-]', 'g'), '\\$&');
}

function wildCompare(str, search) {
    return str.match(new RegExp('^' + preg_quote(search).replace(/\\\*/g, '.*').replace(/\\\.\*/g, '\*') + '$')) !== null;
}

请注意,为了逃避角色,您需要使用\\*代替\*(因为后者逃离*并转变为*做任何事。