Неправильная работа регулярки... Или я что-то делаю не так?
Хочу с помощью регулярки вернуть новый массив, удовлетворяющий моим условиям:
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.. Я был уверен каждая итерация это новый вызов... С большой строкой я понимал)
Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.
Пока нет других ответов. Будьте первым, кто поможет автору.
Ответить на вопрос
Проблема, с которой вы столкнулись, скорее всего связана с неправильным использованием регулярного выражения в вашем коде. Для начала, давайте разберемся, как правильно использовать регулярные выражения в PHP.
В PHP для работы с регулярными выражениями используется функция preg_match(). Эта функция принимает три аргумента: само регулярное выражение, строку, в которой ищется соответствие, и переменную, в которую будет записан результат поиска.
Пример использования preg_match():
$string = "Пример строки для поиска"; $pattern = "/пример/i"; // Ищем слово "пример" без учета регистра if (preg_match($pattern, $string)) { echo "Соответствие найдено!"; } else { echo "Соответствие не найдено."; }
Если у вас возникают проблемы с работой регулярного выражения, возможно, вы неправильно задаете шаблон поиска. Убедитесь, что ваше регулярное выражение корректно отражает шаблон, который вы хотите найти в строке. Также обратите внимание на использование специальных символов в регулярных выражениях, они могут влиять на результат поиска.
Если у вас остались конкретные вопросы или примеры кода, пожалуйста, предоставьте их для более детального анализа проблемы.