Более точный шаблон регулярных выражений - PullRequest
0 голосов
/ 21 сентября 2018

Я сделал подпрограмму фильтра подстановочных знаков для сопоставления имен файлов с использованием подстановочных знаков.Например: *.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' ) невозможно, недопустимо, поэтому fnmatch является более точным?

1 Ответ

0 голосов
/ 21 сентября 2018

Я думаю, что используемая вами функция может быть излишней.Вам просто нужно заменить все вхождения подстановочных знаков на эквивалентное регулярное выражение и сопоставить начало и конец ввода.Это должно работать:

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
...