Регулярное выражение JavaScript загадочным образом не соответствует слову «теннис»

0

Мы написали небольшой скрипт в JavaScript, чтобы найти дубликаты или потенциальные дубликаты. Сценарий работает иногда, но он не таинственно на некоторых словах, таких как "теннис". Мы используем jQuery.

шаги:

1) Нажмите демоверсию JSFiddle здесь: http://jsfiddle.net/6Hgex/.

2) Нажмите " Проверить дюпы".

3) В разделе " Повторить слова" слово " теннис" должно содержать две записи, одну для просмотра теннисного матча и одну для подачи теннисного мяча. Однако по какой-то причине регулярное выражение терпит неудачу при проверке фразы для теннисного мяча - если мы не заменим переменные и значения жесткого кода с помощью инструментов разработчика Chrome. Все значения выглядят правильно, когда мы используем точки останова, но RegEx не подходит для этой фразы.

Вы знаете, что мы делаем неправильно?

Благодарю!

JavaScript:

    // Init page
    $( document ).ready( function() {
        init();
    });


    function init() {
        $( '#box .button.dupe_clues' ).on( 'mousedown', function() {
            var dupe_words_list = $( '.list.dupe_words' );
            dupe_words_list.empty();
            var dupe_words = ['tennis'];
            var unique_clues = ['watching tennis match', 'serving tennis ball'];
            $( dupe_words ).each( function() {
                var highlighted_clues = highlight_dupe_word( unique_clues, this );
                dupe_words_list.append( '<div>' + this + ': ' + highlighted_clues + '</div>' );
            });
        });
    }


function highlight_dupe_word( clues, word ) {
    var list = '';

    // Find all clues containing this word
    var escaped_word = word.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
    var re = new RegExp( '\\b' + escaped_word + '\\b', 'gi' );
    $( clues ).each( function(i, text) {
        if ( re.test( text ) ) {
            list = list + ', ' + text;
        }
    });

    // Trim leading comma
    if ( list.length > 0 ) {
        list = list.substring( 2, list.length + 1 );
    }

    // Return list
    return ( list );
}

HTML:

<div id='box'>
    <textarea id='clues'>
                 watching tennis match
                 serving tennis ball       
    </textarea>

    <div class='button_box'>
        <div class='button dupe_clues'>Check Dupes</div>
    </div>


    <div class='results'>
        <div class='title'>Safe Clues</div>
        <div class='unique_clues list'></div>
        <div class='title'>Repeat Words</div>
        <div class='dupe_words list'></div>
        <div class='title'>Dupe Clues</div>
        <div class='dupe_clues list'></div>
    </div>
</div>
  • 0
    Для отладки нужно много кода, но ваша проблема не в регулярном выражении; измените свой список подсказок, чтобы показывать только watching hockey match , playing hockey game и holding hockey stick . Вы получите правильное повторяющееся слово, но снова только два из трех появятся. Это где-то в ваших итерациях .each или в .each if/else .
  • 3
    Пожалуйста, упростите демонстрацию и код до минимума, чтобы повторить проблему. Нет необходимости вставлять больше, чем просто несколько слов, или отображать методы, которые работают
Показать ещё 9 комментариев

1 ответ

5
Лучший ответ

Не используйте флаг g.

var re = new RegExp( '\\b' + escaped_word + '\\b', 'i' );

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

  • 0
    аааа, интересно так что даже если строка меняется, регулярное выражение запоминает свою позицию?
  • 0
    @ Крашалот, да. Подробности см. В разделах ECMA 15.10.6.3 RegExp.prototype.test (строка) и 15.10.6.2 RegExp.prototype.exec (строка) .
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню