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

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

На снимке экрана ниже столбец «Сумма» может содержать «,» между цифрами. Наш клиент требует, чтобы при поиске «247» (используя поле поиска) такие значения, как «2,47...» или такие, как «247» в столбце, выделялись.

Я попытался решить это с помощью регулярных выражений, но это не сработало, как ожидалось:

const regex = new RegExp(
  searchTerm
  ?.toString()
  .replace(/[.*+?^${}()|[\]\\]/g, "\\$&")
  .replace(/\s+/g, "|") + ",?",
  "gi"
);

Как выделить «2,47» в предыдущем примере?

const regex = new RegExp(
  247
  ?.toString()
  .replace(/[.*+?^${}()|[\]\\]/g, "\\$&")
  .replace(/\s+/g, "|") + ",?",
  "gi"
);

console.info('247','247'.match(regex))
console.info('2,47','2,47'.match(regex))
console.info('2.47','2.47'.match(regex))

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

markalex 17.04.2023 11:52

Может ли ваш ввод позволить ввести , для начала? Вы, кажется, набрали «247» в своем примере, спрашивая о «24,7». Запятая в вашем коде, кажется, используется для разделения элементов поиска, вы можете подтвердить?

Kaddath 17.04.2023 12:00

Почему вы изобретаете свой собственный язык поверх синтаксиса регулярных выражений — переводите поисковый запрос в регулярное выражение, используя ряд подобных сверток? Поисковый запрос обычно состоит из букв, цифр и пробелов, иногда в кавычках и обязательно с запятой (,). Это интерпретируется как есть большинством парсеров регулярных выражений, включая RegExp. Для всего остального он будет проанализирован, как и ожидалось — если пользователь хочет найти 2,47, регулярное выражение 2,47 будет соответствовать строке 2,47. Не усложняйте вещи — это то, из-за чего вы попали в беду.

Armen Michaeli 17.04.2023 12:04

В приведенном выше примере столбец, содержащий сумму, будет иметь «,» между числами. Наш клиент требует, чтобы при поиске 247 в строке поиска выделялось количество, содержащее 2,47, или любое значение, имеющее 247.

Vimal 17.04.2023 12:14

Одним из подходов для такого варианта использования было бы сгенерировать все возможные наборы строк (в приведенном выше случае ["2,47", "24,7", "247"]), а затем искать включение этих строк в данные для поиска. Когда я говорю о включении, я имею в виду data.forEach(str=>str.includes(item[0])), но это все еще кажется неправильным подходом.

JJY9 17.04.2023 14:22
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
2
5
60
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Из ваших разъяснений я не вижу другого выбора, кроме как разделить вашу строку и динамически вставить необязательный ,? между всеми вашими символами. Кажется излишним, но я не вижу другого способа игнорировать комы.

ОКОНЧАТЕЛЬНОЕ РЕДАКТИРОВАНИЕ благодаря markalex: Более чистая версия, ,? теперь добавляются только между цифрами. Таким образом, это можно сделать в конце после экранирования специальных символов и не нужны хакерские приемы, которые могут повлиять на надежность.

Также не нужно вставлять последний ,?, он не будет иметь никакого эффекта

const regex = new RegExp(
  247
  ?.toString()
  .replace(/[.*+?^${}()|[\]\\]/g, "\\$&")
  .replace(/(?<=\d)(?=\d)/g, ",?")
  .replace(/\s+/g, "|"),
  "gi"
);

console.info('regex: ',
  247
  ?.toString()
  .replace(/[.*+?^${}()|[\]\\]/g, "\\$&")
  .replace(/(?<=\d)(?=\d)/g, ",?")
  .replace(/\s+/g, "|")
)

console.info('247','247'.match(regex))
console.info('2,47','2,47'.match(regex))
console.info('2.47','2.47'.match(regex))

const regex2 = new RegExp(
  'question?'
  ?.toString()
  .replace(/[.*+?^${}()|[\]\\]/g, "\\$&")
  .replace(/(?<=\d)(?=\d)/g, ",?")
  .replace(/\s+/g, "|"),
  "gi"
);

console.info('regex: ',
  'question?'
  ?.toString()
  .replace(/[.*+?^${}()|[\]\\]/g, "\\$&")
  .replace(/(?<=\d)(?=\d)/g, ",?")
  .replace(/\s+/g, "|")
)

console.info('question?','question?'.match(regex2))
console.info('question','question'.match(regex2))

Это решение приведет к неожиданному поведению, если строка поиска содержит ?. a?b будет преобразовано в a,?\,??,?b,?.

markalex 17.04.2023 12:32

Это именно то, что я ожидал. Невероятно большое спасибо @Kaddath.

Vimal 17.04.2023 12:49

@markalex это не совсем неожиданное поведение, они просто не будут совпадать. Я исправил регулярное выражение, чтобы включить их, это немного хакерски, должен быть более чистый способ. Все равно спасибо, что заметили!

Kaddath 17.04.2023 12:53

@Kaddath, под неожиданным я имел в виду, что поисковый запрос a?b не найдет a?b себя.

markalex 17.04.2023 13:01

@markalex Я вижу, это термин, который имеет другое значение (и худшие последствия) по сравнению с теми, которые кодируют на C. Я думаю, что это должно быть исправлено сейчас, но они могут быть еще одним крайним случаем.

Kaddath 17.04.2023 13:03

Да, верно: мой плохой. "нежелательное поведение" было бы лучше, я думаю) Что касается крайних случаев: сейчас \\ не будет соответствовать \,\, но я сомневаюсь, что это желательно в любом случае. Что касается самого чистого решения: может быть, .replace(/(?<=\d)(?=\d)/g, ",?") будет лучше? Он будет вставлять ,? только между цифрами.

markalex 17.04.2023 13:16

@Vimal Я обновил свой ответ благодаря markalex. Теперь это проще и надежнее

Kaddath 17.04.2023 17:41

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

Другой подход может заключаться в том, чтобы хранить сумму в формате числа, например 12345, или строки «12345» в БД. Это сделало бы очень простым и эффективным выполнение запроса на поиск/поиск по этим данным.

Теперь с целью форматирования на стороне пользовательского интерфейса, например, суммы $ XX, XXX. Вы можете легко использовать функцию маски.

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

Привет, это, вероятно, должен был быть комментарий, а не ответ. Ни в вопросе, ни в моем ответе нет ничего такого, что не сработает с фунтами. В вопросе ОП нет указаний на то, что числа хранятся уже отформатированными. Этот пост посвящен сопоставлению цифр в отображаемой строке результата. Не может быть совпадения, если числа отформатированы с пробелами, как во французском языке, но ту же логику из моего ответа можно адаптировать, используя (?:\s|,)? или что-то подобное вместо ,?

Kaddath 17.04.2023 17:50

Другие вопросы по теме