RegExp: Я хочу удалить ненужные слова в предложении. Как мне это сделать? - PullRequest
6 голосов
/ 14 мая 2009

У меня есть предложение, и я хочу удалить из него несколько слов.

Итак, если у меня есть:

"jQuery is a Unique language"

и массив с именем garbageStrings:

var garbageStrings = ['of', 'the', "in", "on", "at", "to", "a", "is"];

Я хочу удалить «и» и «а» в предложении.

Но если я использую это: / Этот оператор находится внутри цикла for. Я зацикливаю все предложение и нахожу совпадение в garbageStrings /

var regexp = new RegExp(garbageStrings[i]);

строка станет "jQuery Unique lnguge"

Обратите внимание, что в предложении исключено слово "a".

Я не собирался этого делать.

Ответы [ 6 ]

12 голосов
/ 14 мая 2009

Примерно так:

function keyword(s) {
    var words = ['of', 'the', 'in', 'on', 'at', 'to', 'a', 'is'];
    var re = new RegExp('\\b(' + words.join('|') + ')\\b', 'g');
    return (s || '').replace(re, '').replace(/[ ]{2,}/, ' ');
}
4 голосов
/ 14 мая 2009

Я мог бы поклясться, что JavaScript имел \b (граница слова), но похоже, что нет, попробуйте вместо этого:

var regex  = new RegExp("( |^)" + "a" + "( |$)", "g");
var string = "I saw a big cat, it had a tail.";

string = string.replace(regex, "$1$2");
3 голосов
/ 14 мая 2009

Во-первых, если вы собираетесь проходить через каждый возможный тип "garbageString", использовать Regex совершенно не нужно.

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

Этот код не работает, если есть знаки препинания, но не должно быть слишком сложно изменить код в соответствии с вашими потребностями.

var text = "jQuery is a Unique language";
var garbageStrings = {"of": true,
                      "the": true,
                      "in": true,
                      "on": true,
                      "at": true,
                      "to": true,
                      "a": true,
                      "is": true};

var words = text.split(" ");
var newWords = Array()
for (var i = 0; i < words.length; i++) {
    if (typeof(garbageStrings[words[i]]) == "undefined") {
        newWords.push(words[i]);
    }
}
text = newWords.join(" ");
0 голосов
/ 15 мая 2009

Как сказал Уомблтон. ;)

За исключением того, что я бы удалил пробелы как часть самого регулярного выражения, а не использовал бы второе регулярное выражение для этого (для лучшей производительности):

var re = new RegExp("\\b(?:"+ words.join("|") + ")\\b\\s*", "gi");
s.replace(re, "");

Регулярное выражение будет скомпилировано при создании объекта. При повторных операциях это не должно быть заметно медленнее, чем циклически проходить по каждому стоп-слову с помощью операции строка / массив, и его гораздо легче понять.

Если у вас просто короткий статический список стоп-слов, вместо этого вы можете написать собственное оптимизированное регулярное выражение:

var re = new RegExp("\\b(?:at?|i[ns]|o[fn]|t(?:he|o))\\b\\s*", "gi");
"jQuery is a Unique language".replace(re, "");

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

0 голосов
/ 14 мая 2009

Пожалуйста, не используйте RegExp для этого, он грязный и ненужный, и занимает слишком много циклов. Легче:

var garbageStrings = ['of', 'the', "in", "on", "at", "to", "a", "is"];
for(var i=0; i < garbageString.length; i++){
    string.replace(" "+garbageStrings[i]+" ", "");
}

или с использованием массивов:

var garbageStrings = ['of', 'the', "in", "on", "at", "to", "a", "is"];
var str = str.split(" ");
for(var i=0; i < garbageStrings.length; i++){
    for(var j=0; j < str.length; j++){
        if(str[j].toLowerCase() === garbageStrings[i]){
            str.splice(j, 1);
        }
    }
}
str = str.join(" ");
0 голосов
/ 14 мая 2009

Во-первых, для этого вам нужно использовать массивы, а не регулярные выражения, потому что они будут быстрее. Регулярное выражение на несколько порядков сложнее и, следовательно, слишком тяжело. Как говорит Этвуд, программист считает, что может решить проблему с помощью регулярного выражения. Тогда у него две проблемы.

Итак, ниже приведена быстрая реализация, которая использует ваш список строк мусора и выполняет свою работу, используя встроенную скорость словаря javascript для проверки, является ли слово мусором или нет, и с обработкой знаков препинания. Есть небольшая тестовая страница , на которой вы можете ее попробовать.

function splitwords(str) {
  var unpunctuated = unpunctuate(str);
  var splitted = unpunctuated.split(" ");
  return splitted;
}

function unpunctuate(str) {
  var punctuation = ['.', ',', ';', ':', '-'];
  var unpunctuated = str;
  for(punctidx in punctuation) {
    punct = punctuation[punctidx];
    // this line removes punctuation. to keep it, swap in the line below.
    //unpunctuated = unpunctuated.replace(punct," "+punct+" ");
    unpunctuated = unpunctuated.replace(punct,"");
  }
  return unpunctuated;
}


var garbageStrings = ['of', 'the', "in", "on", "at", "to", "a", "is"];

var garbagedict= {};

for(garbstr in garbageStrings) {
  garbagedict[garbageStrings[garbstr]] = 1;
}

function remove(str) {
  words = splitwords(str);
  keeps = [];
  for(wordidx in words) {
    word = words[wordidx];
    if(word in garbagedict) {
      // ignore
    } else {
      keeps.push(word);
    }
  }
  return keeps.join(" ");
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...