繁体   English   中英

JavaScript 替换仅在使用组时在正则表达式的完全匹配时执行

[英]JavaScript replace only executes on complete match of the regex when using groups

我正在尝试使用以下模式创建输入掩码:“4.01.05.01-6”。 在 onchange 方法中,我执行了一个使用 replace 方法的 function:

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。

使用可选的非捕获组使正则表达式的所有部分,但第一个部分是可选的。 然后,您可以在用作替换参数的回调 function 中检查每个可选组是否匹配,并动态构建替换字符串。

请参阅 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>

正则表达式 - 查看其在线演示- 匹配:

  • ^ - 字符串的开头
  • (\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 ): on digit
  • [\w\W]* - 任何零个或多个字符(如果键入更多字符,则截断输入字符串)
  • $ - 字符串结束。

替换是使用三元运算符构建的,如果b匹配,则附加一个点加b值,如果匹配cd ,同样发生,如果有e组匹配,a -e组值.

我想不出任何办法只用正则表达式。 我认为你应该用输入的长度来判断,所以当输入的长度是 3 位时,然后只像这样运行这些数字的替换

if(value.length >= 2 && value.length <= 3){
value.replace(
/^(\d{1})(\d{1,2})/,
'$1.$2'
)
}

对数字长度为 4 - 5 等的情况执行相同操作。

所以整个代码可能是这样的

if(value.length >= 2 && value.length <= 3){
value.replace(
/^(\d{1})(\d{1,2})/,
'$1.$2'
)
}else if(value.length >= 4 && value.length <= 5){
value.replace(
/^(\d{1})(\d{2})(\d{1,2})/,
'$1.$2.$3'
)
}else if(value.length >= 6 && value.length <= 7){
value.replace(
/^(\d{1})(\d{2})(\d{2})(\d{1,2})/,
'$1.$2.$3.$4'
)
}else if(value.length == 8){
value.replace(
/^(\d{1})(\d{2})(\d{2})(\d{2})(\d{1})/,
'$1.$2.$3.$4-$5'
)
}

也许我在上面的代码中有一些错误,但我认为你明白了

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM