Проблема регулярных выражений в JavaScript - PullRequest
0 голосов
/ 16 марта 2010

Я создаю небольшую игру Yahtzee и столкнулся с некоторыми проблемами с регулярными выражениями. Мне нужно проверить определенные критерии, чтобы убедиться, что они выполнены. Поля с первого по шестой очень просты, проблема возникает после этого. Как попытка создать регулярное выражение, соответствующее лестнице. Straight должен содержать один из следующих символов 1-5. Он должен содержать по одному для прохождения, но я не могу понять, как это проверить. Я думал /1{1}2{1}3{1}4{1}5{1}/g;, но это только соответствует, если они приходят в порядок. Как я могу проверить, не пришли ли они в правильном порядке?

Ответы [ 6 ]

3 голосов
/ 16 марта 2010

Если я вас правильно понял, вы хотите проверить, содержит ли строка числа от 1 до 5 в случайном порядке. Если это правильно, то вы можете использовать:

var s = '25143';
var valid = s.match(/^[1-5]{5}$/);
for (var i=1; i<=5; i++) {
  if (!s.match(i.toString())) valid = false;
}

Или:

var s = '25143';
var valid = s.split('').sort().join('').match(/^12345$/);
2 голосов
/ 17 марта 2010

Хотя это определенно можно решить с помощью регулярных выражений, я нахожу довольно интересным и познавательным предоставить «чистое» решение, основанное на простой арифметике. Это выглядит так:

function yahtzee(comb) {

    if(comb.length != 5) return null;

    var map = [0, 0, 0, 0, 0, 0];
    for(var i = 0; i < comb.length; i++) {
        var digit = comb.charCodeAt(i) - 48;
        if(digit < 1 || digit > 6) return null;
        map[digit - 1]++;
    }

    var sum = 0, p = 0, seq = 0;
    for(var i = 0; i < map.length; i++) {
        if(map[i] == 2) sum += 20;
        if(map[i] >= 3) sum += map[i];

        p = map[i] ? p + 1 : 0;
        if(p > seq) seq = p;
    }

    if(sum == 5)  return "Yahtzee";
    if(sum == 23) return "Full House";
    if(sum == 3)  return "Three-Of-A-Kind";
    if(sum == 4)  return "Four-Of-A-Kind";

    if(seq == 5) return "Large Straight";
    if(seq == 4) return "Small Straight";

    return "Chance";
}

для справки, правила Яхтзе

1 голос
/ 17 марта 2010

Регулярное выражение, вероятно, не лучшее решение для этой проблемы, но для развлечения:

/^(?=.*1)(?=.*2)(?=.*3)(?=.*4)(?=.*5).{5}$/.test("12354")

Это соответствует каждой строке, которая содержит ровно пять символов, являющихся числами 1-5, с одним из каждого.

(?=.*1) - позитивный взгляд, по сути говоря, "справа от нас должно быть все, что следует или ничего, за которым следует 1".

Lookahead не "потребляют" какую-либо частьрегулярного выражения, поэтому каждая проверка числа начинается с начала строки.

Затем есть .{5}, чтобы фактически использовать пять символов, чтобы убедиться, что их правильное число.

1 голос
/ 17 марта 2010

с регулярным выражением:

return /^([1-5])(?!\1)([1-5])(?!\1|\2)([1-5])(?!\1|\2|\3)([1-5])(?!\1|\2|\3|\4)[1-5]$/.test("15243");

(Не то, чтобы это рекомендовалось ...)

1 голос
/ 16 марта 2010
"12543".split('').sort().join('') == '12345'
1 голос
/ 16 марта 2010

Для простоты и легкости я бы пошел с indexOf.

string.indexOf(searchstring, start)

Цикл от 1 до 5, как у Макса, но просто проверьте indexOf i, разбейте на ложные значения.

Это также поможет для небольшого стрита, который составляет только 4 из 5 (12345 или 23456). Изменить: Woops. 1234, 2345, 3456. Извините.

Вы могли бы даже иметь обобщенную функцию для проверки прямых произвольной длины, передавая максимальный индекс цикла, а также строку для проверки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...