正则表达式找到电话号码中的重复模式?或许不是吗?

时间:2016-01-09 15:45:54

标签: javascript regex

我想找到一个带有图案的数字,在几千个列表中,我希望匹配以下内容:

  • 3个或更多个序列,任一方向(345,2345,876)
  • 重复序列(2233,3355,77777)147,258,369或其反向。
  • 重复模式(373737,33773377)

在像这样的JSON对象中:

["ok", {"series/020" : ["02034353637", "02034445673", "02034147369", "02034653185"]}]

所以这些都匹配;例如,第一个有34 35 36,第二个有444和567,最后一个有147和/或369等。

我尝试了什么?好吧,那个小盒子里的大多数网站都在右边唠叨我! Stackoverflow搜索。一些在线书籍......但是当我找到142 page book时,我开始怀疑是否存在“正则表达式诵读困难”(regexia?)这样的事情,或者可能只是厚度。我知道我什么时候被击败。

事后看来,在Google表格自动填充的帮助下手动构建模式可能会更快更轻松地进行“阵列搜索阵列”,但这是否可能?

最后,是否有“付我10美元,我会为你做你的正则表达式”网站?如果没有,他们应该!他们做了一个薄荷!谢谢。

2 个答案:

答案 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");