我想找到一个带有图案的数字,在几千个列表中,我希望匹配以下内容:
在像这样的JSON对象中:
["ok", {"series/020" : ["02034353637", "02034445673", "02034147369", "02034653185"]}]
所以这些都匹配;例如,第一个有34 35 36,第二个有444和567,最后一个有147和/或369等。
我尝试了什么?好吧,那个小盒子里的大多数网站都在右边唠叨我! Stackoverflow搜索。一些在线书籍......但是当我找到142 page book时,我开始怀疑是否存在“正则表达式诵读困难”(regexia?)这样的事情,或者可能只是厚度。我知道我什么时候被击败。
事后看来,在Google表格自动填充的帮助下手动构建模式可能会更快更轻松地进行“阵列搜索阵列”,但这是否可能?
最后,是否有“付我10美元,我会为你做你的正则表达式”网站?如果没有,他们应该!他们做了一个薄荷!谢谢。
答案 0 :(得分:4)
你可以写一个RegEx,但为了便于阅读,我就这样写了:
var data = ["ok", {
"series/020": [
"02034353637", "02034445673", "02034147369", "02034653185",
"345", "2345", "876",
"2233", "3355", "77777",
"147", "258", "369",
"373737", "33773377",
]
}]
var numbers = data[1]["series/020"]
var patternNumbers = numbers.filter(isPatternNumber)
// Demo output
document.write("<pre>" + JSON.stringify(patternNumbers, null, "\t") + "</pre>")
document.write("Matched " + patternNumbers.length + " out of " + numbers.length)
function isPatternNumber(n) {
// constant pattern
if (/147|258|369/.test(n)) return true
// repeating pattern 3+
if (/(?=(\d))\1{3,}/.test(n)) return true
// sequence asc 3+
if (/012|123|234|345|456|567|678|789/.test(n)) return true
// sequence desc 3+
if (/987|876|765|654|543|432|321/.test(n)) return true
// repeating double sequence xxyy (note that x=y is possible, same as 4 in a row)
if (/(?=(\d))\1{2}(?=(\d))\2{2}/.test(n)) return true
// alternerting pattern xyxy (note that x=y is possible, => same as 4 in a row)
if (/(?=(\d))\1{1}(?=(\d))\2{1}(?=(\d))\1{1}(?=(\d))\2{1}/.test(n)) return true
return false
}
// Demo Input
var input = document.getElementsByTagName("input")[0]
var output = document.getElementsByTagName("span")[0]
input.oninput = function() {
output.textContent = isPatternNumber(input.value)
}
Test a number:
<input type="text" /> <span></span>
答案 1 :(得分:1)
重复数字和重复模式非常简单
(\d+?)\1+
假设这是总正则表达式中的第一个/唯一括号
序列需要更多的努力,特别是如果我们谈论动态长度的序列。 我写了一个小的JS函数来构建这样一个正则表达式
function sequencedDigitsRegex(minLength, maxLength){
//the last digit
var t = "'+a[0]+'?";
//the optional Part
for(var i=1; i<maxLength - minLength; ++i)
t = "(?:'+a["+(i%10)+"]+'" + t + ")?";
//the required part
for(t = "'" + t + "'"; minLength>0; --minLength)
t = "a["+(i++%10)+"] + " + t;
//a template-method
var template = new Function("a", "return " + t);
var digits = "98765432109876543210".split("");
//the regex-parts
var out = new Array(20);
for(var i=0; i<10; ++i){
var a = digits.slice(i, i+10);
out[i] = template(a);
//also include the reversed variant
out[i+10] = template(a.reverse());
}
//join the parts into one, long regex
return new RegExp("("+out.join("|")+")", "g")
}
如果你想把它们组合起来,你可以做某事。像这样:
var repeatingPattern = /(\d+?)\1+/g;
var sequencePattern = sequencedDigitsRegex(2,8);
var patterns = new RegExp(repeatingPattern.source + "|" + sequencePattern.source, "g");