代码之家  ›  专栏  ›  技术社区  ›  Codebeat

更精确的通配符regexp

  •  0
  • Codebeat  · 技术社区  · 7 年前

    我做了一个通配符过滤器例程来匹配使用通配符的文件名。例如: *.js 给我一个目录中的所有js文件。

    然而,当有 .json 文件在目录中,我也得到这些。我明白为什么,但那不是我想要的。

    我使用这个wildcardStringToRegexp函数(从一个站点获取)来构建RegExp(因为我不擅长这个):

    function wildcardStringToRegexp( s ) 
    {
        if( isValidString( s ))
         { return false; }
    
        function preg_quote(str, delimiter) 
        {
            // *     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 (str + '').replace(new RegExp('[.\\\\+*?\\[\\^\\]$(){}=!<>|:\\' + (delimiter || '') + '-]', 'g'), '\\$&');
        }
    
    
        return new RegExp(preg_quote(s).replace(/\\\*/g, '.*').replace(/\\\?/g, '.'), 'g');
    }
    

    function fnmatch( sMask, sMatch, bReturnMatches )
    {
        if( !isValidString( sMatch ))
         { return false; }
    
        var aMatches = sMatch.match( wildcardStringToRegexp( sMask ) );
    
        if( bReturnMatches )
         { return isValidArray( aMatches )?aMatches:[]; }
    
        return isValidArray( aMatches )?aMatches.length:0;
    }  
    

    fnmatch( '*.js', 'myfile.js' )   returns 1
    fnmatch( '*.js', 'myfile.json' ) returns 1 , this is not what I want
    

    我怎样才能换衣服 wildcardStringToRegexp ()函数,或者我需要什么来改变它 fnmatch( '*.js', 'myfile.json' ) 是不可能的,是无效的,所以匹配更精确?

    1 回复  |  直到 7 年前
        1
  •  2
  •   sliptype    7 年前

    我认为你使用的功能可能有点过头了。只需将所有出现的通配符替换为regex等价项,并匹配输入的开头和结尾。这应该起作用:

    const fnmatch = (glob, input) => {
    
      const matcher = glob
                      .replace(/\*/g, '.*')
                      .replace(/\?/g, '.'); // Replace wild cards with regular expression equivalents
      const r = new RegExp(`^${ matcher }$`); // Match beginning and end of input using ^ and $
      
      return r.test(input);
     }
    
    console.log(fnmatch('*.js', 'myfile.js')); // true
    console.log(fnmatch('*.js', 'myfile.json')); // false
    console.log(fnmatch('?yfile.js', 'myfile.js')); //true