我正在尝试创建具有以下模式的输入掩码:“4.01.05.01-6”。在 onchange 方法中,我执行一个使用替换方法的函数:
value = value
.replace(/\D/g, '')
.replace(
/^(\d{1})(\d{2})(\d{2})(\d{2})(\d{1})/,
'$1.$2.$3.$4-$5'
)
问题是,当我有 8 位数字时,我只有在正则表达式完全匹配后才收到屏蔽的输入值。那不是我想要的。我想输入输入内容,并且掩码将在我输入时起作用,例如,如果我刚刚输入“1234”,我希望得到值“1.23.4”
OBS: 我不关心以下信息,但我使用带有受控输入的 React,这个名为“value”的变量用于创建 setState。
最佳答案
使用可选的非捕获组使正则表达式的所有部分(除了第一个部分)可选。然后,您可以检查每个可选组是否在用作替换参数的回调函数中匹配,并动态构建替换字符串。
查看 JavaScript 演示:
function App() {
const [Version, setVersion] = React.useState('')
function maskVersion({ target: { value } }) {
const re = /^(\d)(?:(\d{1,2})(?:(\d{1,2})(?:(\d{1,2})(\d)?)?)?)?[\w\W]*$/
setVersion(value.replace(/\D/g,'').replace(re, (_,a,b,c,d,e) =>
a +
( b ? `.${b}` : "") +
( c ? `.${c}` : "") +
( d ? `.${d}` : "") +
( e ? `-${e}` : "") ))
}
return <div>
Text: <input type='text' onChange={maskVersion} value={Version} />
</div>
}
ReactDOM.render(<App/>, document.querySelector('#root'))
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root"></div>
正则表达式 - 请参阅 its online demo - 匹配:
^
- 字符串开头(\d)
- 捕获组 1 (a
):一位数字(?:(\d{1,2})(?:(\d{1,2})(?:(\d{1,2})(\d)?)?) ?)?
- 可选的非捕获组匹配(\d{1,2})
- 捕获组 2 (b
):一位或两位数字(?:(\d{1,2})(?:(\d{1,2})(\d)?)?)?
- 可选的非捕获组匹配(\d{1,2})
- 捕获组 3 (c
):一位或两位数字(?:(\d{1,2})(\d)?)?
- 可选的非捕获组匹配(\d{1,2})
- 捕获组 4 (d
):一位或两位数字(\d)?
- 可选捕获组 5 (e
):数字
[\w\W]*
- 任意零个或多个字符(如果输入更多字符则 chop 输入字符串)$
- 字符串结尾。
使用三元运算符构建替换,如果 b
匹配,则附加一个点加 b
值,如果 c
或 d
匹配,同样的情况发生,如果有 e
组匹配,则出现 -
和 e
组值已添加。
关于使用组时,JavaScript 替换仅在正则表达式完全匹配时执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65562980/