连续数字的正则表达式

时间:2014-04-08 08:48:12

标签: java regex

我想检查一个数字是否连续,例如:

12345是连续的,但54321也是连续的。

现在我使用的正则表达式只说12345是连续的。

String consecutive = "^(?:0?123(45?)?|1?23456?|2?34567?|3?45678?|4?56789?|(5?6)?7890?|\n" +
                "         (0?1)?2345678?(90$)?|1?23456789?|2?345678(90?)?)$";

如何更改此正则表达式以匹配另一个?它必须是5位数。

这个正则表达式有更好的方法吗?

5 个答案:

答案 0 :(得分:3)

我不认为正则表达式是这个问题的正确答案。尽管如此(但不寒而栗!):

Pattern regex = Pattern.compile(
    "\\b                                                       \n" +
    "(?:                                                       \n" +
    " (?:                                                      \n" +
    "  0(?=1|\\b)|                                             \n" +
    "  1(?=2|\\b)|                                             \n" +
    "  2(?=3|\\b)|                                             \n" +
    "  3(?=4|\\b)|                                             \n" +
    "  4(?=5|\\b)|                                             \n" +
    "  5(?=6|\\b)|                                             \n" +
    "  6(?=7|\\b)|                                             \n" +
    "  7(?=8|\\b)|                                             \n" +
    "  8(?=9|\\b)|                                             \n" +
    "  9\\b         # or 9(?=0|\\b) if you want to allow 890123\n" +
    " )+                                                       \n" +
    " |                                                        \n" +
    " (?:                                                      \n" +
    "  9(?=8|\\b)|                                             \n" +
    "  8(?=7|\\b)|                                             \n" +
    "  7(?=6|\\b)|                                             \n" +
    "  6(?=5|\\b)|                                             \n" +
    "  5(?=4|\\b)|                                             \n" +
    "  4(?=3|\\b)|                                             \n" +
    "  3(?=2|\\b)|                                             \n" +
    "  2(?=1|\\b)|                                             \n" +
    "  1(?=0|\\b)|                                             \n" +
    "  0\\b         # or 0(?=9|\\b) if you want to allow 321098\n" +
    " )+                                                       \n" +
    ")                                                         \n" +
    "\\b", 
    Pattern.COMMENTS);
Matcher regexMatcher = regex.matcher(subjectString);

live on regex101.com

答案 1 :(得分:1)

正如这个问题的许多其他评论员,我认为这不应该用正则表达式完成。如果你想匹配重复的数字模式(如111),而不是任意数字序列(如123246),则正则表达式很酷。由于我对这个主题感兴趣,我编写了这段代码。 输入字符串可以是任何字符序列(与非数字混合的数字),并且将返回给定长度的所有连续数字

public class ConNumberParser {

    public static List<String> findConsecutiveNumbers(String s, int length) {
        LinkedList<String> matches = new LinkedList<>();

        // seek to first digit
        int i = 0;
        while (i < s.length() && !Character.isDigit(s.charAt(i))) {
            i++;
        }
        // store the beginning of a consecutive series
        Integer matchedIndex = i;
        // and the direction
        Boolean increasing = null;

        for (i++; i < s.length(); i++) {
            final char c = s.charAt(i);
            if (Character.isDigit(c)) {
                if (null == matchedIndex) {
                    // first digit after other characters
                    matchedIndex = i;
                    increasing = null;
                    continue;
                }
                int difference = Character.getNumericValue(c) - Character.getNumericValue(s.charAt(i - 1));
                if (Math.abs(difference) > 1) {
                    // no conescutive digits
                    matchedIndex = i;
                    increasing = null;
                    continue;
                }
                if (length > 2) {
                    if (null == increasing) {
                        // found first consecutive digit
                        increasing = (difference == 1);
                        continue;
                    }
                    final int expectedDiff = increasing ? 1 : -1;
                    if (difference != expectedDiff) {
                        // no conescutive digits in the right direction
                        matchedIndex = i - 1;
                        increasing = (difference == 1);
                        continue;
                    }
                }
                if (i - matchedIndex + 1 == length) {
                    // consecutive digits of given length found
                    matches.add(s.substring(matchedIndex, matchedIndex + length));
                    matchedIndex++; // move by one to keep matching overlapping
                                    // sequences
                }
            } else {
                matchedIndex = null;
            }
        }

        return matches;
    }

    public static void main(String[] args) {
        String test = "A12345b321";
        List<String> m = findConsecutiveNumbers(test, 3);
        System.out.print(test + " length=3: ");
        System.out.println(m.toString());

        String test2 = "Ax.*1290134543b3210";
        List<String> m2 = findConsecutiveNumbers(test2, 3);
        System.out.print(test2 + " length=3: ");
        System.out.println(m2.toString());

        List<String> m3 = findConsecutiveNumbers(test2, 2);
        System.out.print(test2 + " length=2: ");
        System.out.println(m3.toString());
    }

}

产生预期结果:

A12345b321 length=3: [123, 234, 345, 321]
Ax.*1290134543b3210 length=3: [345, 543, 321, 210]
Ax.*1290134543b3210 length=2: [12, 01, 34, 45, 54, 43, 32, 21, 10]

答案 2 :(得分:0)

发现regex很难,所以我这样做了:

  public static boolean isConsecutive(final String pinCode)
{
    int [] digits = new int [pinCode.length()];
    int [] differences = new int [pinCode.length()-1];
    int temp = 0;

    for(int i = 0; i < pinCode.length(); i++)
        digits[i] = Integer.parseInt(String.valueOf(pinCode.charAt(i)));

    for(int i = 0; i < digits.length -1; i++)
        differences[i] = Math.abs(digits[i] - digits[i+1]);

    if(differences.length != 0) {
        temp = differences[0];
        for (int i = 1; i < differences.length; i++)
            if (temp != differences[i])
                return false;
    }

    return true;
}

答案 3 :(得分:0)

这个怎么样?

function test(r) {
    s = r.toString();
    if(s.length == 2) {
        return Math.abs(parseInt(s.split('')[0]) - parseInt(s.split('')[s.length-1])) == 1;
    } else {
        t = parseInt(s.split('')[0]) + parseInt(s.split('')[s.length-1]); 
        s = '' + (parseInt(s) + parseInt(s.split('').reverse().join(''))) / t;
        return new RegExp('1{' + s.split('').length + '}').test(s);
    }
}

答案 4 :(得分:-3)

它需要是正则表达式吗?在我的头顶,您可以将任何包含的字符串拆分为字符,转换为数字,然后检查b = a + 1 || b = a - 1(在开始时设置一些标志,以确定是否正在递增或递减。


修改

帖子here可能会帮助您。

这是它建议的正则表达式:

/(^|(.)(?!\2))(\d)\3{3}(?!\3)/(N.B.这仅适用于4个字符)