Помощь с регулярным выражением соответствия строки JavaScript, особый случай - PullRequest
0 голосов
/ 21 января 2019

Здравствуйте, у меня есть база данных JSON, в которой мне нужно сопоставлять пользовательский ввод с ключевыми словами.Я имел успех с этим, за исключением одного особого случая.В основном, если пользователь вводит «мороженое», должно быть совпадение с ключевым словом или строкой «мороженое».

Я попытался удалить пробел в "мороженом", чтобы сделать его "мороженым", но затем он сводит на нет многие другие совпадения, такие как "мороженое", которое превращается в "мороженое".Есть ли регулярное выражение, которое будет работать в этом случае?

var input = new RegExp("icecream", "i");
var keywords = "ice cream, ice cream cone, plastic container lid";

if (keywords.search(input) != -1) {

//do Something

}

Должно быть найдено совпадение между "мороженым" и "мороженым", также если бы я искал "пластиковую крышку" вместо "пластиковой"крышка контейнера ", которая также должна найти совпадение.Любая помощь очень ценится.В конечном счете, я ищу решение, которое могло бы решить все ситуации, а не только "мороженое" или "мороженое", в частности.

Ответы [ 5 ]

0 голосов
/ 21 января 2019

Tl, др

var input = new RegExp('icecream'.split('').join('(\\s)*').concat('|icecream'), 'i');
var keywords = "ice cream, ice cream cone, plastic container lid";

if (keywords.search(input) != -1) {

//do Something

}

Полный ответ:

Чтобы ответить на ваш вопрос, я предложил следующий метод:

function makeRegEx(input) {
  // The regex for an optional whitespace.
  let glueRegex = '(\\s)*';

  // Transform the string into an array of characters.
  let splittedString = input.split('');

  // Join the characters together, with the optional whitespace inbetween.
  let joinedString = splittedString.join(glueRegex)

  // Add the actual input as well, in case it is an exact match.
  joinedString += '|' + input;

  // Make a new regex made out of the joined string.
  // The 'i' indicates that the regex is case insensitive.
  return new RegExp(joinedString, 'i');
}

Это создаст новый RegEx, который помещает дополнительный пробел между каждым символом.

Это означает, что с данной строкой icecream вы получите RegEx, который выглядит следующим образом:

/i(\s)*c(\s)*e(\s)*c(\s)*r(\s)*e(\s)*a(\s)*m/i

Это регулярное выражение будет соответствовать во всех следующих случаях:

  • я cecream
  • ic ecream
  • мороженое <= Это ваше! </li>
  • ледяное поле
  • icecr eam
  • Ледяной берег
  • Мороженое, м
  • 1035 * мороженное *

Весь метод также может быть сокращен до этого:

let input = new RegExp(input.split('').join('(\\s)*').concat(`|${input}`), 'i');

Он довольно короткий, но также нечитаемый.


Встроенный в ваш код, он выглядит так:

function makeRegEx(input) {
  // The regex for an optional whitespace.
  let glueRegex = '(\\s)*';

  // Transform the string into an array of characters.
  let splittedString = input.split('');

  // Join the characters together, with the optional whitespace inbetween.
  let joinedString = splittedString.join(glueRegex)

  // Add the actual input as well, in case it is an exact match.
  joinedString += '|' + input;

  // Make a new regex made out of the joined string.
  // The 'i' indicates that the regex is case insensitive.
  return new RegExp(joinedString, 'i');
}



let userInput = 'icecream';
let keywords = "ice cream, ice cream cone, plastic container lid";

let input = makeRegEx('icecream');

// Check if any of the keywords match our search.
if (keywords.search(input) > -1) {
  console.log('We found the search in the given keywords on index', keywords.search(input));
} else {
  console.log('We did not find that search in the given keywords...');
}

Или это:

var input = new RegExp('icecream'.split('').join('(\\s)*').concat('|icecream'), 'i');
var keywords = "ice cream, ice cream cone, plastic container lid";

if (keywords.search(input) != -1) {

//do Something

}
0 голосов
/ 21 января 2019

В приведенном ниже решении я не использую регулярное выражение, но создаю новый список ключевых слов на основе комбинации двух слов (между запятыми) из предыдущего списка.

var input1 = "ice cream"
var input2 = "icecream"
var input3 = "plastic lid"

var keywords = "ice cream, ice cream cone, plastic container lid";

let merge = a => {
    let result=[a.join(' ')];
    a.forEach((x,i)=>{  
        for(let j=i+1; j<a.length; j++) result.push(x+a[j])  
        for(let j=i+1; j<a.length; j++) result.push(x+' '+a[j])  
    });
    return result;
} 

let moreKeywords = keywords.split(', ').map( k=> merge(k.split(' ')) ).flat();

if(moreKeywords.includes(input1)) console.log('contains',input1);
if(moreKeywords.includes(input2)) console.log('contains',input2);
if(moreKeywords.includes(input3)) console.log('contains',input3);

console.log('moreKeywords:', moreKeywords);
0 голосов
/ 21 января 2019

Вам нужен поиск, чтобы быть регулярным выражением? Если этого достаточно, чтобы просто выполнить поиск по ключевому слову, вы можете использовать indexOf и сначала удалить пробелы

var input = 'icecream';
var keywords = "ice cream, ice cream cone, plastic container lid";

if (keywords.replace(/\s/g, '').toLowerCase().indexOf(input) != -1) { alert('success!'); }

Редактировать: модификация для включения различных поисков

var searches = ['icecream', 'cashcow', 'takeout', 'otherthing']; // array with your searches
var keywords = "ice cream, ice cream cone, plastic container lid"; // input by the user

var tmpKeywords = keywords.replace(/\s/g, '').toLowerCase(); // remove spaces and convert to all lower case
var length = searches.length;
for (var i=0; i<length; i++) { // loop through all the seach words
    if (tmpKeywords.indexOf(searches[i]) != -1) {
        console.log(searches[i] + ' exists in the input!');
    }
}
0 голосов
/ 21 января 2019

Вы можете сделать это так:

let iceexpression=/ice\s*cream/g
let input="testinput icecream";
if(input.search(iceexpression)){
console.log("found");
}
0 голосов
/ 21 января 2019

Вы можете использовать подстановочный знак, такой как /ice *cream/g

Вы можете опробовать свое регулярное выражение здесь и прочитать на разных входах здесь

Вот обновленный пример для работы с любым вводом

var keywords = "ice cream, ice cream cone, ice cream c, plastic container lid";


  function search()
  {
    var textToFind = document.getElementById("searchInput").value;
    var input = new RegExp(textToFind.toString() + "*", "i");
    var words = keywords.split(",");
    words.forEach(function(word) {
      if(word.match(input))
      {
       console.log(word);
      }
    });
  }
<input id="searchInput"\>
<button id="search" onclick="search()">search</button>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...