Регулярное выражение дробное число или дробное число с % знаком

Не могу придумать и завершить идею. У меня проблема что правило на вод точки не работает, я могу вести больше одного раза знак точка или запятая.

Мой вариант который работает, но есть ошибки в нем. Я пробовал заменить все найденые варианты, ничего не работает. Надо такого вида чтоб была запись

onkeyup="this.value = this.value.replace (/^\d+(?:[.,]\d{1,2}%?)?$/g, '')"

Идея input поле можно вести число дробное но оно может быть и проценое число, для опредление этого конце потавить знак %.

Тесты на проверку

true

10 
8.6
10.3%
150.5
23.23
500.5%

false

.2%
.20%
..20
..20%
12.444
12.444%
12. 12
10%%

Желатально чтоб работа все из такого условия сразу. Если надо выносить в функцию и через ее прогонять, тогда пример 100% рабочий покажите, просто регулярку кинуть без возможности проверить на живом примере нету смысла. Я такие регулярные выражение находил а заставить работать не возмонжо.

<input  type="text" onkeyup="this.value = this.value.replace (/[^\d+(,|\.)?\d{0,2}%]+/g, '')">

Ответы (2 шт):

Автор решения: EzioMercer

Можете попробовать так, но единнственная загвоздка - это если человек введёт 5. и решит на этом остановиться, тогда вам надо будет обработать этот случай во время сабмита (например добавить 0 в конце):

const input = document.querySelector('#input');
const regexp = /^\d+(\.\d{0,2})?%?$/;

let oldValue = input.value;

input.addEventListener('input', (e) => {
  const newValue = e.target.value;
  
  if (regexp.test(newValue) || newValue === '') input.value = oldValue = newValue;
  else input.value = oldValue;
});
<input type="text" id="input">

→ Ссылка
Автор решения: Laukhin Andrey

Предложу более универсальный вариант, при этом достаточно простой.
Шаблон на проверку задаем в атрибуте pattern элемента input. В этом случае, чтобы мы не ввели в поле, браузер перед отправкой формы сделает проверку. При этом мы можем дать пользователю понять ошибку, подсвечивая поле, например, красным. Дополнительно можно ограничить ввод неразрешенных символов.
Компромиссный вариант, который настраивается под любые правила:

const symbols = /[\d.,%]/;
let input = document.getElementById('input');

input.addEventListener('keydown', function(e) {
  if (e.key.length == 1 && !symbols.test(e.key)) e.preventDefault();
});

input.addEventListener('input', function(e) {
  this.checkValidity() ?
    this.style.backgroundColor = 'white' :
    this.style.backgroundColor = 'red';
});
<form onsubmit="return false">
  <input id="input" type="text" pattern="^\d+(?:[.,]\d{1,2})?%?$" />
  <button>Отправить</button>
</form>
Можно сделать дополнительную проверку при потере фокуса, чтобы вынудить пользователя исправить ошибку.

→ Ссылка