javascript 中的正则表达式只允许数字和一个点后跟最多 2 个数字

regex in javascript allow only numbers and one dot followed by max 2 number

使用 javascript 我想限制一个内容可编辑的单元格,只允许数字和一个点,并且点后最多 2 个数字

有效示例:

在我的例子中

function onlyNumberAndADot(element) {
  const invalidChars = /\D/g;
  ob = element.target;
    if (invalidChars.test(ob.textContent)) {
      ob.textContent = ob.textContent.replace(invalidChars, "");
    }
}

document.getElementById("test1").addEventListener("input", function(event) {
  onlyNumberAndADot(event);
})
#test1 {
  border: 1px solid gray;
  padding: 5px;
  width: 100px;
}
<table class="table">
  <tbody>
    <tr>
      <td id="test1" contenteditable="true"></td>
    </tr>
  </tbody>
</table>

仅在纯javascript 我正在尝试这个:[0-9]?(.+)?[0-9]{1,2} 但它不正常而且我不知道如何实现我的功能

not a correct example... because of number 6546545.55

使用字边界限制小数:

[0-9]?\.?[0-9]{1,2}\b
//          here __^^

或更好:

\b\d+(?:\.\d\d?)?\b

您可以对虚线部分使用带组的正则表达式。

/^[1-9]*\d?(\.\d{1,2})?$/

console.log(['2', '0.2', '0.35', '.5', '.22', '4.55', '6.4', '6546545.55', '-1', '0.', '00', '00.0', '.123'].map(s => /^[1-9]*\d?(\.\d{1,2})?$/.test(s)));
.as-console-wrapper { max-height: 100% !important; top: 0; }

您需要在多个 if else 语句中执行此操作,因为这是一个输入标签,您可能会在用户在其上键入时立即更新。

所以首先:你需要 test/match 如果它只是数字或者它是一个点 var digitsAndDot = /[0-9\.]$/ 然后做一些事情关于它,或者你可以检查它是否是非数字除了点 /[^0-9\.]$/ 用它做点什么。

第二:如果字符串已经有一个点 (.) /\./ 则只允许输入数字。

第三:找到如果你不想让这个“0.1.2.”出现 var duplicate = /.\d{0,2} $/ 然后做一些事情,例如继续删除数字输入的其余部分(超过两个)并且不允许更多的点。

你也可以把值转成数组然后操作它。

每次你的事件处理程序运行时,输入都会增加一个字符,所以我认为更好的方法是检查输入是否仍然匹配你的正则表达式规则,如果不匹配,恢复以前的值并强制它模糊().

尝试像这样更新您的事件处理程序,它应该可以工作:

let curValue = '';
function onlyNumberAndADot(event) {
  const valid = /^\d*\.?(?:\d{1,2})?$/;
  const text = event.target.textContent;  
  if (!valid.test(text)) {
    event.target.textContent = curValue;
    event.target.blur();
  } else {
    curValue = event.target.textContent;
  }
}

document.getElementById("test1").addEventListener("input", function(event) {
  onlyNumberAndADot(event);
});

document.getElementById("test1").addEventListener("blur", function(event) {
  event.target.textContent = event.target.textContent.replace(/\.$/,'');
});

我用这个解决方案创建了一个 fiddle 并且它有效。

注意你必须暂时允许像'0.'这样的输入,否则用户将无法输入点,所以我对模糊事件进行了另一次验证,以删除最后的'.'

这应该涵盖您的所有情况。

/^(?:\d+(?:\.\d{1,2})?|\.\d{1,2})$/

可读版本

 ^ 
 (?:
      \d+ 
      (?: \. \d{1,2} )?
   |  \. \d{1,2} 
 )
 $

聊天后

更新

似乎正则表达式需要在实时事件处理程序中对输入进行操作,
比如按键贴等等。

为此,它需要是渐进式可选类型的正则表达式
允许部分匹配,但去除无效文本。

那个正则表达式是
查找 /^(\d+(?:\.\d{0,2})?|\.\d{0,2})?.*?$/
替换 ""

可读版本

 ^ 
 (                             # (1 start)
      \d+ 
      (?:
           \. 
           \d{0,2} 
      )?
   |  \. \d{0,2} 
 )?                            # (1 end)
 .*? 
 $

提交当前条目时,最终验证正则表达式可以
是必要的,但也许不是。

正则表达式是这样的 ^(?:\d+(?:\.\d{0,2})?|\.\d{1,2})$

唯一可能的失效永远只是一个点或一个空白
这是有效的 当前输入 但在决赛中无效。

如果不匹配,只需将输入设置为 0,然后从那里开始。


更新

要限制在每个事件中重写输入文本,请添加一对
处理程序中额外的 filter 步骤。

var RxFinalForm = /^(?:\d+(?:\.\d{0,2})?|\.\d{1,2})$/;
var RxRmvInvalid = /[^\d.]+/g;
var RxPartialForm = /^(\d+(?:\.\d{0,2})?|\.\d{0,2})?.*?$/;

function onlyNumber(element) { 
 ob = element.target; 
 var sContent = ob.textContent;

 // Test if the current content is a valid Final Form.
 // Note the ob.textContent does not need to be changed,
 // thus preserving the caret position.
 // -----------------------------------------------------
 if ( RxFinalForm.test( sContent ) )
    return;  // No need to change anything, just return

 // Remove any invalid characters ( non - dot/digit )
 // --------------------------------------------------
 sContent = sContent.replace( RxRmvInvalid, "" );

 // Extract the Partial Form
 // -------------------------
 sContent = sContent.replace( RxPartialForm, "");

 // Finally, if 'ob.textContent' does not equal 'sContent', change it.
 // This will happens when an extra dot was enterred.
 // ------------------------------------------------------------------
 if ( ob.textContent !== sContent )
    ob.textContent = sContent;
}