Неправильная работа регулярки... Или я что-то делаю не так?

Ссылка скопирована
1 ответ

Хочу с помощью регулярки вернуть новый массив, удовлетворяющий моим условиям:

let names = ['Vladimir', 'Olga', 'Denis', 'Ludmila', 'Max', 'Ekaterina'] let reg = /a/gi let filtered = names.filter(name => reg.test(name)) console.log(filtered)

let names = ['Vladimir', 'Olga', 'Denis', 'Ludmila', 'Max', 'Ekaterina'] let reg = /a/gi let filtered = names.filter(name => reg.test(name)) console.log(filtered)

Но на выходе получается неправильный массив ('Max' отсутствует, хотя удовлетворяет условию):

// [object Array] (4) ["Vladimir","Olga","Ludmila","Ekaterina"]

// [object Array] (4) ["Vladimir","Olga","Ludmila","Ekaterina"]

https://codepen.io/LaCosteGreen/pen/yLZQZqv

Дополнительно:

https://codepen.io/LaCosteGreen/pen/yLZQZqv

let reg = /a/i
Читаем, что делает флаг g.

  • Спасибо большое, работает! Но не понял почему такое поведение... Флаг g не останавливает поиск при первом вхождении... Как в этой ситуации, этот флаг не даёт результат - не понимаю(
  • LaCosteGreen, флаг g сохраняет позицию (индекс) последнего совпадения, соответственно новый поиск начнется с последнего индекса, а не с 0
  • Спасибо! Нигде такого не видел в описании..
  • LaCosteGreen, тут важно понимать логику работы регулярки. вот к примеру -
    let arr = ['ba','ab','ba','ab'] let reg = /a/gi let filtered = arr.filter(str => reg.test(str)) console.log(filtered) // вывод [ 'ba', 'ba' ]

    let arr = ['ba','ab','ba','ab'] let reg = /a/gi let filtered = arr.filter(str => reg.test(str)) console.log(filtered) // вывод [ 'ba', 'ba' ]

    но в то же время

    let arr = ['ab','ba','b','ab','ba'] let reg = /a/gi let filtered = arr.filter(str => reg.test(str)) console.log(filtered)  //вывод [ 'ab', 'ba', 'ab', 'ba' ]

    let arr = ['ab','ba','b','ab','ba'] let reg = /a/gi let filtered = arr.filter(str => reg.test(str)) console.log(filtered) //вывод [ 'ab', 'ba', 'ab', 'ba' ]

    Вопрос - почему? Нужно смотреть по итерациям, держа в памяти сказанное в ответе о том, что индекс последнего найденного элемента запоминается регуляркой.

    let arr = ['ba','ab','ba','ab'] let reg = /a/gi let filtered = arr.filter(str => reg.test(str)) /*итерация первая(ba): регулярка ищет букву А и находит ее на  индексе 1(нумерация у нас с 0). Окей, буква есть,  поэтому возвращаем  true  Итерация вторая(ab): регулярка запомнила индекс, по которому  нашла первую букву, и поэтому начинает поиск с индекса 1.  Там у нас только b,поэтому возвращаем false.  ВНИМАНИЕ, ФОКУС!Если регулярное выражение, как в нашем  случае, не нашло совпадение, оно "забывает" индексы.  То есть считается что весь текст проверен.  Следующая итерация будет искать с начала. Поэтому... Итерация третья () Итерация третья(ab) - смотри итерацию первую*/ console.log(filtered) // вывод [ 'ba', 'ba' ]

    let arr = ['ba','ab','ba','ab'] let reg = /a/gi let filtered = arr.filter(str => reg.test(str)) /*итерация первая(ba): регулярка ищет букву А и находит ее на индексе 1(нумерация у нас с 0). Окей, буква есть, поэтому возвращаем true Итерация вторая(ab): регулярка запомнила индекс, по которому нашла первую букву, и поэтому начинает поиск с индекса 1. Там у нас только b,поэтому возвращаем false. ВНИМАНИЕ, ФОКУС!Если регулярное выражение, как в нашем случае, не нашло совпадение, оно "забывает" индексы. То есть считается что весь текст проверен. Следующая итерация будет искать с начала. Поэтому... Итерация третья () Итерация третья(ab) - смотри итерацию первую*/ console.log(filtered) // вывод [ 'ba', 'ba' ]

    Такое поведение может оказаться неочевидным при первом использовании. Да и по факту выходит что использование флага g в циклах - плохая идея если ты точно не знаешь зачем это тебе.

Ответы:

Спасибо всем большое! Я вроде разобрался) в моём примере получается что перед 'Max' регулярка останавливается и запоминает что остановился на 'Ludmila' (индекс a = 6) и в следующей итерации 'Max' поиск и начинается с этого индекса (6) а в Max всего 3 позиции.... Очень неочевидно при методе filter.. Я был уверен каждая итерация это новый вызов... С большой строкой я понимал)

Нужно решить такую задачу?

Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.

Заказать помощь
Лучший ответ
1
Андрей PHP Ответ

Проблема, с которой вы столкнулись, скорее всего связана с неправильным использованием регулярного выражения в вашем коде. Для начала, давайте разберемся, как правильно использовать регулярные выражения в PHP.

В PHP для работы с регулярными выражениями используется функция preg_match(). Эта функция принимает три аргумента: само регулярное выражение, строку, в которой ищется соответствие, и переменную, в которую будет записан результат поиска.

Пример использования preg_match():

$string = "Пример строки для поиска";
$pattern = "/пример/i"; // Ищем слово "пример" без учета регистра
if (preg_match($pattern, $string)) {
    echo "Соответствие найдено!";
} else {
    echo "Соответствие не найдено.";
}

$string = "Пример строки для поиска"; $pattern = "/пример/i"; // Ищем слово "пример" без учета регистра if (preg_match($pattern, $string)) { echo "Соответствие найдено!"; } else { echo "Соответствие не найдено."; }

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

Если у вас остались конкретные вопросы или примеры кода, пожалуйста, предоставьте их для более детального анализа проблемы.

Другие ответы (0)

Пока нет других ответов. Будьте первым, кто поможет автору.

Ответить на вопрос

комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Вам также может быть интересно