Регулярное выражение для сопоставления чисел >= 150 000 с включенными пробелами не работает должным образом

Я пытаюсь создать регулярное выражение, которое соответствует числам, большим или равным 150 000, рассматривая пробелы как разделители тысяч. Вот регулярное выражение, которое я пробовал:

^(150\s*000|1[5-9]\d{2}(\s*\d{3})*|[2-9]\d{2}(\s*\d{3})*|\d{1,2}(\s*\d{3})+)$

Вот код JavaScript, который я использовал для его тестирования:

const regex = /^(150\s*000|1[5-9]\d{2}(\s*\d{3})*|[2-9]\d{2}(\s*\d{3})*|\d{1,2}(\s*\d{3})+)$/;
const testStrings = [
    "149 000",
    "151 000",
    "185 000",
    "800 152",
    "15 000",
    "100 000",
    "200 000",
    "250 000 123",
    "100 0000",
    "150 000",
];

testStrings.forEach(testString => {
const matches = testString.match(regex);
if (matches) {
    console.info(`Matched: ${testString}`);
} else {
    console.info(`Did not match: ${testString}`);
}});

Однако результаты не такие, как ожидалось:

  • Не совпало: 149 000
  • Не совпало: 151 000
  • Не совпало: 185 000
  • Соответствует: 800 152
  • Совпало: 15 000
  • Не совпало: 100 000
  • Сопоставлено: 200 000
  • Соответствует: 250 000 123
  • Не совпало: 100 0000
  • Сопоставлено: 150 000

Кажется, проблема связана с первой частью регулярного выражения. Что я делаю неправильно?

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

<input type = "radio" required name = "myname"  cf-label = "Non" value = "non" cf-conditional-price = "^(150\s*000|1[5-9]\d{2}(\s*\d{3})*|[2-9]\d{2}(\s*\d{3})*|\d{1,2}(\s*\d{3})+)$" />

Всегда ли значения в массиве числовые? Если да, то я бы предложил более простое решение — привести их к числовому типу и просто использовать >= 150_000

Rory McCrossan 09.07.2024 12:01

Согласен с @RoryMcCrossan... просто проведите числовое сравнение.

Tim Biegeleisen 09.07.2024 12:03
1[5-9]\d{2} должно быть 1[5-9]\d. 100 0000 не следует вашей логике регулярных выражений, где вы допускаете только пробелы между группами цифр. Если вас не волнуют пробелы в номере, просто удалите их перед проверкой.
Wiktor Stribiżew 09.07.2024 12:03

Я использую библиотеку, в которой не могу изменить ввод, это только строки с отформатированными цифрами.

Jihane 09.07.2024 12:04

Regex не подходит для сравнения значений строк или чисел. Пожалуйста, рассмотрите возможность сделать то, что предложил @RoryMcCrossan.

evolutionxbox 09.07.2024 12:07

@Jihane, тогда это идеально подходит для приведения типов и математического сравнения, а не для регулярных выражений.

Rory McCrossan 09.07.2024 12:12

И если вам нужно сопоставить даже любые пробелы между каждой цифрой, вам нужно их учитывать, т. е. ^\s*(?:1\s*5\s*0\s*0\s*0\s*0|1\s*[5-9]\s*\d(?:\s*\d\s*\d\s*\‌​d)*|[2-9]\s*\d\s*\d(‌​?:\s*\d\s*\d\s*\d)*|‌​\d(?:\s*\d)?(?:\s*\d‌​\s*\d\s*\d)+)\s*$ (см. демо).

Wiktor Stribiżew 09.07.2024 12:16

По вашим правилам, "100 0000" недействителен — так и должно быть? Вы утверждаете "не так, как ожидалось... не соответствует 100 0000" - но это правильно, оно не должно совпадать.

fdomn-m 09.07.2024 12:41
Поведение ключевого слова "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) для оценки ваших знаний,...
1
8
86
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Почему вам следует использовать регулярное выражение?

Мы можем подойти к этому, сначала преобразуя строковые значения в числовые значения.

let testStrings = [
    "149 000",
    "151 000",
    "185 000",
    "800 152",
    "15 000",
    "100 000",
    "200 000",
    "250 000 123",
    "100 0000",
    "150 000",
];

testStrings = testStrings.map((str) => Number(str.replace(/\s/g, "")));

testStrings.forEach((value) => {
    if (value >= 150000) {
        console.info(`Matched: ${value}`);
    } else {
        console.info(`Did not match: ${value}`);
    }
});

Ваш ответ, скорее всего, будет отклонен из-за дополнительной причины регулярного выражения: I have to put this regex in HTML because it is the only way to allow this condition

mplungjan 09.07.2024 12:30

Ага, тему отредактировали после того, как я на нее ответил.

Dicky Indra Asmara 15.07.2024 12:24
Ответ принят как подходящий

Вот регулярное выражение, которое, похоже, работает с вашими критериями любого числа >= 150 000 с пробелами, заменяющими запятые:

/\b((1[5-9]\d|[2-9]\d{2}|\d{4,})(\s\d{3})+)\b/

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

Вот готовый код, заменяющий ваше регулярное выражение:

const regex = /\b((1[5-9]\d|[2-9]\d{2}|\d{4,})(\s\d{3})+)\b/;

const testStrings = [
    "149 000",
    "151 000",
    "185 000",
    "800 152",
    "15 000",
    "100 000",
    "200 000",
    "250 000 123",
    "100 0000",
    "150 000"
];

testStrings.forEach(testString => {
    const matches = testString.match(regex);
    if (matches) {
        console.info(`Matched: ${testString}`);
    } else {
        console.info(`Did not match: ${testString}`);
    }
});

Большое спасибо, это отлично работает. Я знаю, что регулярное выражение — не лучшее решение, но библиотека, которую я использую, ограничивает меня этим решением.

Jihane 09.07.2024 12:35

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

KillerCube 09.07.2024 12:44

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