一般问题
如果该模式之前已匹配N次,如何阻止正则表达式匹配?
具体示例
我有一个13位数的记录标识符,用户将在文本字段中键入,例如“123-456-7891011”。
我试图封装的行为是在键入第4和第7位数字之前添加破折号。我有处理事件的所有javascript没有问题。
它始终是数字 - 我在此特定步骤之前处理它。
当我每次输入第n + 4位数字时,我能够正确地使用正则表达式来插入短划线。我需要的是它在第二个“ - ”
之后的任何时候都不要这样做到目前为止,我在事件处理程序(oninput
)中最接近的是:
var addDash = /([^\-\d{3}]*\d{3})(\d+)/;
this.value = this.value.replace(addDash, "$1-$2");
例如,输入“1234567891011”会产生“123-456-789-101-1”,其中我想要的是“123-456-7891011”。
可能其他方式可以处理这种情况(例如split
和join
)但是出于这个问题的目的,让我们坚持回答正确的正则表达式模式,如果这样的模式是可能的。还有其他事情会使这种模式变得非常有用 - 我只是没有运气了。
为了清晰,此模式将在文本字段上运行oninput
- 匹配应适用于1到13之间的任意字符长度:
"123456" -> "123-456"
"123456789" -> "123-456-789"
"1234567891011" -> 123-456-7891011"
答案 0 :(得分:3)
使用callbacks。
您可以将函数指定为第二个参数。在这种情况下,将在执行匹配后调用该函数。函数的结果(返回值)将用作替换字符串。
针对您当前需求的解决方案是改变模式并始终进行完全匹配:
this.value = this.value.replace(/^(\d{3})-?(\d{3})?-?(\d*)$/, function (m, a, b, c) {
return b ? a + "-" + b + "-" + c : a + "-" + c;
});
完成工作。
如果您想要更通用的解决方案,可以使用计数器变量:
var count = 0;
this.value = this.value.replace(/(\d{3})-?/g, function (m, a) {
return ++count <= 2 ? a + "-" : m;
});
这个模式使用的模式不太适合您的需求,但它可以演示如何推广到真正需要限制替换次数的不同情况。
顺便说一句,你有一种语法误解:[^\-\d{3}]
不意味着你的想法。它将匹配单个字符,该字符不是数字或其中任何一个:-
,{
或}
。 [
... ]
括号内的所有内容都定义了字符类,因此{n}
等量词在那里毫无意义。
答案 1 :(得分:1)
您可以在替换中使用回调,以及如何处理分隔符的一些逻辑。这样可以更轻松地获得您期望的行为。
var values = ['12', '123', '123-4', '123-45', '123-456', '123-456-7', '123-456-7891011'];
var addDash = /^(\d{3})-?(\d?\d?\d?)-?(\d*)/;
values.forEach(function(value) {
value = value.replace(addDash, function(match, capture1, capture2, capture3) {
var secondDelimiter = capture2.length == 3 ? '-' : '';
return capture1 + '-' + capture2 + secondDelimiter + capture3;
});
})
console.log(values)
&#13;
答案 2 :(得分:0)
使用正则表达式而无需额外的JS:
var addDash = /^((\d{3}\-?)(\d{3}\-?)?)(\d)$|^(\d{3})(\d)$/;
this.value = this.value.replace(addDash, "$1$5-$4$6");
从字符串的开头开始,使用可选的&#34; - &#34;以及可选的3个数字匹配3位数字,然后紧跟字符串末尾的最后一位数字。如果不匹配,请查看字符串是否以3位数字开头,后面紧跟字符串末尾的最后一位数字。
使用替换字符串中的捕获组获得一点时髦,以实现所需的格式。
答案 3 :(得分:-3)
$(function() {
var txt='1232';
var addDash = /^(\d{3})-?(\d?\d?\d?)-?(\d*)/;
$("#test").html(txt.replace(addDash, function(match, capture1, capture2, capture3) {
var firstDelimiter = (capture1.length == 3 && capture2.length > 0) ? '-' : '';
var secondDelimiter = (capture2.length == 3 && capture3.length > 0) ? '-' : '';
return capture1 + firstDelimiter + capture2 + secondDelimiter + capture3;
}));
})