Другие способы удалить или игнорировать знаки препинания в JS, кроме регулярного выражения?

Я решаю некоторые проблемы с Coderbyte для начинающих и столкнулся с интересной дилеммой. Вот проблема:

«Используя язык JavaScript, пусть функция LongestWord(sen) принимает передаваемый параметр sen и возвращает самое большое слово в строке. Если есть два или более слова одинаковой длины, верните первое слово из строки с этим значением. длина. Не обращайте внимания на знаки препинания и предположите, что sen не будет пустым".

Вот мой код:

function LongestWord(sen) {
    var myArray = sen.split(" ");
    var lengthOfSubstring = 0;

    for (var i = 0; i < myArray.length; i++) {
        if (myArray[i].length > lengthOfSubstring) {
            lengthOfSubstring = myArray[i].length;
            sen = myArray[i];
        }
    }
    return sen;
}

console.log(LongestWord("Argument goes here"));

Мой код проходит все тесты, если аргумент не содержит знаков препинания. Можно ли как-то удалить или проигнорировать? Каждый поиск вызывает регулярное выражение и очень пугающий синтаксис, ха-ха

РЕДАКТИРОВАТЬ: использовал метод match() для параметра sen, любезно предоставленный @Markus

function LongestWord(sen) {
    var myArray = sen.match(/[a-z]+/gi);
    var lengthOfSubstring = 0;

    for (var i = 0; i < myArray.length; i++) {
        if (myArray[i].length > lengthOfSubstring) {
            lengthOfSubstring = myArray[i].length;
            sen = myArray[i];
        }
    }
    return sen;
}
console.log(LongestWord("Argument goes here"));

person jakewies    schedule 26.04.2015    source источник
comment
Не пугайтесь регулярных выражений. Прими это. Альтернативы намного уродливее и пугающе.   -  person ThisClark    schedule 27.04.2015
comment
@adeneo — в вопросе говорится помимо регулярного выражения (и пунктуация включает гораздо больше символов, чем точка).   -  person Quentin    schedule 27.04.2015
comment
Regex чертовски быстр, суперкомпактен и сэкономит вам сотни строк кода в будущем. И этому даже не так уж сложно научиться. Не пугайтесь этого! Даже после изучения основ некоторые проблемы, связанные со строками, станут для вас тривиальными.   -  person Shashank    schedule 27.04.2015
comment
хорошо, я сейчас читаю кое-какую документацию. Мой вопрос остается в силе, из любопытства. Является ли регулярное выражение единственным способом добиться этого?   -  person jakewies    schedule 27.04.2015
comment
@Quentin - регулярное выражение для удаления определенной пунктуации, которую ОП хочет удалить, является ответом.   -  person adeneo    schedule 27.04.2015
comment
И нет, регулярное выражение — не единственный способ добиться этого, вы можете разбить все символы на массив, выполнить итерацию, проверить наличие определенных символов и удалить каждый из них, но зачем?   -  person adeneo    schedule 27.04.2015
comment
@adeneo чисто из любопытства   -  person jakewies    schedule 27.04.2015
comment
Давайте закончим обсуждение регулярных выражений и начнем работать над ответом на вопрос, сосредоточившись на помимо регулярных выражений.   -  person ThisClark    schedule 27.04.2015
comment
Regex не так страшен, как кажется на первый взгляд. Они чрезвычайно полезны во многих ситуациях. Ознакомьтесь с руководством по регулярным выражениям MDN, это должно немного демистифицировать вещи. Эта статья также является довольно хорошим введением. Конечно, бывают ситуации, когда регулярное выражение является неправильным инструментом, например анализ HTML .   -  person Useless Code    schedule 27.04.2015


Ответы (3)


Без регулярного выражения:

function LongestWord(sen) {
    var wordStart = -1;
    var bestWord = null;
    var bestLength = 0;

    for (var i = 0; i < sen.length; i++) {
        var ch = sen[i];
        if ('a' <= ch && ch <= 'z' || 'A' <= ch && ch <= 'Z')
        {
            if (wordStart === -1)
            {
                wordStart = i;
            }
        }
        else
        {
            if (wordStart !== -1)
            {
                var word = sen.substring(wordStart, i);
                if (word.length > bestLength)
                {
                    bestLength = word.length;
                    bestWord = word;
                }
                wordStart = -1;
            }
        }
    }
    if (wordStart !== -1)
    {
        var word = sen.substring(wordStart);
        if (word.length > bestLength)
        {
            bestLength = word.length;
            bestWord = word;
        }
        wordStart = -1;
    }
    return bestWord;
}

С регулярным выражением:

function LongestWord(sen) {
    var bestWord = null;
    var bestLength = 0;

    var matches = sen.match(/[a-z]+/gi);
    for (var i = 0; i < matches.length; i++)
        var word = matches[i];
        if (word.Length > bestLength)
        {
            bestLength = word.Length;
            bestWord = word;
        }
    }
    return bestWord;
}
person Markus Jarderot    schedule 26.04.2015
comment
Ницца. Я собирался прокомментировать выше, что сделать это без регулярных выражений было бы намного сложнее. Вы проделали хорошую работу, продемонстрировав это. На мой взгляд, простое изменение одной строки - гораздо лучшее решение. - person DonovanM; 27.04.2015
comment
Я предполагаю, что это проблема в вашем решении - Çüiyaa - person ThisClark; 27.04.2015
comment
Или øæåöéåä€$ и т. д., в основном все, что не является a-z - person adeneo; 27.04.2015
comment
Это потрясающе. Я интегрировал метод match в свой код и работал как часы. Я отредактирую свой исходный пост с измененным кодом, чтобы вы могли видеть, что я сделал. Я никогда не видел/не использовал метод match, но я собираюсь прочитать какой-нибудь документ и ознакомиться с регулярным выражением. Очень признателен! - person jakewies; 27.04.2015
comment
@ЭтоКларк, @аденео. Да. Но это проблема любого решения, поскольку JavaScript не поддерживает сопоставление категорий юникода (\p{L}). Вам нужно будет перечислить все символы, которые вы считаете символами слова (или знаками препинания). - person Markus Jarderot; 27.04.2015

Без регулярного выражения

function LongestWord(sen) {
    var punct = '\.,-/#!$%^&*;:{}=-_`~()'.split('');

    var words = sen.split(" ").map(function(item) {
        return item.split('').filter(function(char) {
            return punct.indexOf(char) === -1;
        }).join('');
    });

    return words.reduce(function(a, b) {
        return a.length > b.length ? a : b;
    });
}

С регулярным выражением

function LongestWord(sen) {
    return sen.split(" ").map(function(word) {
        return word.replace(/[\.,-\/#!$%\^&\*;:{}=\-_`~()]/gi, '');
    }).reduce(function(a, b) {
        return a.length > b.length ? a : b;
    });
}
person adeneo    schedule 26.04.2015
comment
Использование предопределенной строки знаков препинания позволит использовать такие символы, как Çüiyaa. - person ThisClark; 27.04.2015

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

function longestWord(sen) {
    // We are using Python's string.punctuation set.
    var punct = '!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~';
    var wordArr = sen.split(' ');
    var filteredWordArr = wordArr.map(function (word) {
        return word.split('').filter(function (ch) {
            return punct.indexOf(ch) < 0;
        }).join('');
    });
    return wordArr[filteredWordArr.reduce(function (maxIdx, currWord, i, fwa) {
        return currWord.length > fwa[maxIdx].length ? i : maxIdx;
    }, 0)];
}

console.log(longestWord("Çüéâäâ, wouldn't you like to play?")); // wouldn't

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

Однако использование регулярного выражения немного очищает этот код. Это поможет вам заменить операции разделения, фильтрации и объединения одной операцией замены регулярного выражения:

function longestWord(sen) {
    var punct = /[!"#$%&'()*+,\-.\/\\:;<=>?@[\]^_`{\|}~]/g;
    var wordArr = sen.split(' ');
    var filteredWordArr = wordArr.map(function (word) {
        return word.replace(punct, '');
    });
    return wordArr[filteredWordArr.reduce(function (maxIdx, currWord, i, fwa) {
        return currWord.length > fwa[maxIdx].length ? i : maxIdx;
    }, 0)];
}
person Shashank    schedule 26.04.2015
comment
@ThisClark Я позаимствовал пунктуационную строку аденео. Это должно работать для этого сейчас. - person Shashank; 27.04.2015
comment
OP в конце концов выбрал решение с регулярным выражением, но я - - person ThisClark; 27.04.2015