web-dev-qa-db-ja.com

JavaScriptでのワイルドカード文字列比較

"birdBlue""birdRed"、および"pig1""pig2"などの動物と呼ばれる多くの文字列を含む配列があるとします。

ここで、配列を通過し、すべての鳥を返すためのforループを実行します。ここでどのような比較が意味がありますか?

Animals == "bird*"は私の最初のアイデアでしたが、機能しません。演算子*を使用する方法はありますか(または、使用に似たものはありますか?

40
xqz313

たとえば、ワイルドカードとして「*」(スター)のようなものを意味すると思います。

  • 「a * b」=>「a」で始まり「b」で終わるすべて
  • 「a *」=>「a」で始まるすべて
  • 「* b」=>「b」で終わるすべて
  • "* a *" => "a"を含むすべてのもの
  • 「* a * b *」=>「a」が含まれ、すべてが続き、その後に「b」、その後に続くすべてのもの

またはあなたの例では: "bird *" => birdで始まるすべてのもの

同様の問題があり、RegExpで関数を作成しました。

//Short code
function matchRuleShort(str, rule) {
  var escapeRegex = (str) => str.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1");
  return new RegExp("^" + rule.split("*").map(escapeRegex).join(".*") + "$").test(str);
}

//Explanation code
function matchRuleExpl(str, rule) {
  // for this solution to work on any string, no matter what characters it has
  var escapeRegex = (str) => str.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1");

  // "."  => Find a single character, except newline or line terminator
  // ".*" => Matches any string that contains zero or more characters
  rule = rule.split("*").map(escapeRegex).join(".*");

  // "^"  => Matches any string with the following at the beginning of it
  // "$"  => Matches any string with that in front at the end of it
  rule = "^" + rule + "$"

  //Create a regular expression object for matching string
  var regex = new RegExp(rule);

  //Returns true if it finds a match, otherwise it returns false
  return regex.test(str);
}

//Examples
alert(
    "1. " + matchRuleShort("bird123", "bird*") + "\n" +
    "2. " + matchRuleShort("123bird", "*bird") + "\n" +
    "3. " + matchRuleShort("123bird123", "*bird*") + "\n" +
    "4. " + matchRuleShort("bird123bird", "bird*bird") + "\n" +
    "5. " + matchRuleShort("123bird123bird123", "*bird*bird*") + "\n" +
    "6. " + matchRuleShort("s[pe]c 3 re$ex 6 cha^rs", "s[pe]c*re$ex*cha^rs") + "\n" +
    "7. " + matchRuleShort("should not match", "should noo*oot match") + "\n"
);

使用されている機能について詳しく知りたい場合:

79
Spen

RegExpを使用する必要があります(素晴らしい)簡単な解決策は次のとおりです。

if( /^bird/.test(animals[i]) ){
    // a bird :D
}
10
Davsket

Javascriptの substring メソッドを使用できます。例えば:

var list = ["bird1", "bird2", "pig1"]

for (var i = 0; i < list.length; i++) {
  if (list[i].substring(0,4) == "bird") {
   console.log(list[i]);
  }
}

どの出力:

bird1
bird2

基本的に、配列の各項目をチェックして、最初の4文字が「鳥」かどうかを確認しています。これは、「鳥」が常に文字列の先頭にあることを前提としています。


それでは、URLからパス名を取得するとしましょう。

たとえば、bird1?= letsflyで-このコードを使用してURLを確認できます。

var listOfUrls = [
                  "bird1?=letsfly",
                  "bird",
                  "pigs?=dontfly",
                 ]

for (var i = 0; i < list.length; i++) {
  if (listOfUrls[i].substring(0,4) === 'bird') {
    // do something
  }
}

上記は最初のURLに一致しますが、3番目(ブタではない)には一致しません。 url.substring(0,4)を正規表現、または.contains()などの別のjavascriptメソッドと簡単に交換できます。


.contains()メソッドを使用すると、もう少し安全になります。 URL 'bird'のどの部分にいるかを知る必要はありません。例えば:

var url = 'www.example.com/bird?=fly'

if (url.contains('bird')) {
  // this is true
  // do something
}
2
Cody Reichert

*および?ワイルドカードをサポートするスニペットです

let arr = ["birdBlue", "birdRed", "pig1", "pig2" ];
let wild = 'bird*';

let re = new RegExp('^'+wild.replace(/\*/g,'.*').replace(/\?/g,'.')+'$');
let result = arr.filter( x => re.test(x.toLowerCase()) );

console.log(result);
0
var searchArray = function(arr, str){
    // If there are no items in the array, return an empty array
    if(typeof arr === 'undefined' || arr.length === 0) return [];
    // If the string is empty return all items in the array
    if(typeof str === 'undefined' || str.length === 0) return arr;

    // Create a new array to hold the results.
    var res = [];

    // Check where the start (*) is in the string
    var starIndex = str.indexOf('*');

    // If the star is the first character...
    if(starIndex === 0) {

        // Get the string without the star.
        str = str.substr(1);
        for(var i = 0; i < arr.length; i++) {

            // Check if each item contains an indexOf function, if it doesn't it's not a (standard) string.
            // It doesn't necessarily mean it IS a string either.
            if(!arr[i].indexOf) continue;

            // Check if the string is at the end of each item.
            if(arr[i].indexOf(str) === arr[i].length - str.length) {                    
                // If it is, add the item to the results.
                res.Push(arr[i]);
            }
        }
    }
    // Otherwise, if the star is the last character
    else if(starIndex === str.length - 1) {
        // Get the string without the star.
        str = str.substr(0, str.length - 1);
        for(var i = 0; i < arr.length; i++){
            // Check indexOf function                
            if(!arr[i].indexOf) continue;
            // Check if the string is at the beginning of each item
            if(arr[i].indexOf(str) === 0) {
                // If it is, add the item to the results.
                res.Push(arr[i]);
            }
        }
    }
    // In any other case...
    else {            
        for(var i = 0; i < arr.length; i++){
            // Check indexOf function
            if(!arr[i].indexOf) continue;
            // Check if the string is anywhere in each item
            if(arr[i].indexOf(str) !== -1) {
                // If it is, add the item to the results
                res.Push(arr[i]);
            }
        }
    }

    // Return the results as a new array.
    return res;
}

var birds = ['bird1','somebird','bird5','bird-big','abird-song'];

var res = searchArray(birds, 'bird*');
// Results: bird1, bird5, bird-big
var res = searchArray(birds, '*bird');
// Results: somebird
var res = searchArray(birds, 'bird');
// Results: bird1, somebird, bird5, bird-big, abird-song

このような方法には、警告の長いリストと、考慮されていない「what ifs」の長いリストがあり、そのいくつかは他の回答で言及されています。しかし、スター構文を簡単に使用するには、これが良い出発点になるかもしれません。

フィドル

0
James Hay