сопоставление с образцом и проверка диапазона с регулярным выражением в Java - PullRequest
0 голосов
/ 14 ноября 2009

Мое приложение будет в основном принимать пользовательский ввод через метод main (String [] args). Я пытался найти способ сделать некоторую проверку с этим вводом, используя скороговорку.

Каждый допустимый ввод состоит в основном из одного символа : (пробелы следует игнорировать)

* 'R' or 'r' - replay
* 'Q' or 'q' - quit
* [1-6] - perform tasks 1 .. 6

Если пользовательский ввод недействителен - это означает, что если мы обнаружим что-либо, отличное от указанного выше, приложение закроется после отображения сообщения об ошибке.

Итак, вся логика в методе main будет находиться в одном большом условии:

if(Pattern.matches("[RQrq1-6]*", args[0]){

}

У меня возникли некоторые трудности с пониманием метода match с использованием регулярного выражения (вышеупомянутое не работает), и я хотел бы избежать нескольких условий if-else для проверки каждого действительного ввода по отдельности.

Может ли это быть достигнуто с помощью шаблона сопоставления с одновременной проверкой диапазона?

Спасибо за любые подсказки!

Ответы [ 5 ]

3 голосов
/ 14 ноября 2009

Ваше регулярное выражение не совсем верно.

Когда вы пишете: [RQrq1-6]*

Вы говорите, совпадение ноль или более повторений любого символа в квадратных скобках ...

Попробуйте это [RQrq1-6] - что означает совпадение ровно с одним.

Я написал небольшую программу с шипами:

import java.util.regex.Pattern;

public class Spike {

public static void main(String[] args) {
    testIt("Q");
    testIt("q");
    testIt("z");
    testIt("Z");
    testIt("R");
    testIt("r");
    testIt("0");
    testIt("1");
    testIt("2");
    testIt("3");
    testIt("4");
    testIt("5");
    testIt("6");
    testIt("7");
    testIt("02");
    testIt("11");
    testIt("17");
    testIt(""); // should fail, used to pass with the question's regex

}

public static void testIt(String sample) {
    System.out.print(sample+" ");
    if (Pattern.matches("[RQrq1-6]*", sample)) {
        System.out.println("match");
    } else {
        System.out.println("fail");
    }
}

}

Вывод был таким:

Q match
q match
z fail
Z fail
R match
r match
0 fail
1 match
2 match
3 match
4 match
5 match
6 match
7 fail
02 fail
11 match
17 fail
 match

Сняв звезду в регулярном выражении:

Q match
q match
z fail
Z fail
R match
r match
0 fail
1 match
2 match
3 match
4 match
5 match
6 match
7 fail
02 fail
11 fail
17 fail
 fail

Как игнорировать пробелы

Заменить эту версию testit:

public static void testIt(String sample) {
    System.out.print(sample+" ");

    Pattern pattern = Pattern.compile("\\s*([RQrq1-6])\\s*");
    Matcher matcher = pattern.matcher(sample);

    if (matcher.matches()) {
        System.out.println("match '"+matcher.group(1)+"'");
    } else {
        System.out.println("fail");
    }
}

Вот критические строки вывода:

testIt(" 6");// ignore space tests
testIt(" 7");// ignore space tests
testIt("6 ");// ignore space tests
testIt("7 ");// ignore space tests

    6 match '6'
    7 fail
   6  match '6'
   7  fail

Он использует концепцию, называемую «группа захвата». Группа захвата - это часть регулярного выражения, которой присваивается номер, чтобы можно было извлечь конкретную строку символов, которая соответствует. Здесь мы используем группу захвата, чтобы вытащить символ из необязательного пробела.

2 голосов
/ 14 ноября 2009

Я бы соблазнился , а не , чтобы сделать это с регулярным выражением, так как оно будет только сопоставлять и извлекать конкретный шаблон, и не очень поможет с решением, что делать для конкретной строки (используя одно регулярное выражение ).

Вместо этого я бы использовал библиотеку параметров командной строки, такую ​​как Apache Commons CLI . Это гораздо больше подходит для того, что вам нужно.

1 голос
/ 14 ноября 2009

Я думаю, вам нужно сопоставить каждый переданный аргумент. Итак:

for(int i = 0; i < args.length; i++) {
   if (Pattern.matches("[RQrq1-6]+", args[i]){
     <do stuff>
   }
}
0 голосов
/ 15 ноября 2009

Если я правильно прочитал ваш вопрос, вы хотите назвать свою программу так:

$ myprog 153r34r2q

Затем ваша программа просматривает эту строку однобуквенных команд и выполняет их (возможно, что-то, что вы передаете в дальнейших аргументах).

Для этого ваше решение для регулярных выражений почти в порядке (используйте /[RrQq1-6]+/ вместо /[RrQq1-6]*/).

Однако я подозреваю, что вы на самом деле хотите запустить вашу программу, а затем принимать пользовательские команды во время работы программы (это предположение вызвано именами ваших команд «replay» и «quit», которые мало смысл иначе). Для этого args[] вообще не подходит. Вместо этого вам придется использовать основной цикл, который принимает одиночные нажатия клавиш в качестве входных данных. В этом случае я бы не использовал регулярное выражение для проверки отдельного символа, а использовал бы условие switch для отправки различным командам, в которых задан регистр по умолчанию для обнаружения неверного ввода.

Редактировать: После прочтения вашего комментария я предлагаю вам использовать что-то по шаблону команд .

0 голосов
/ 14 ноября 2009

Следующий класс отлично работает для меня (именно так, как я ожидал):

public class Test{
  public static void main(String[] args) throws Exception {
    if(java.util.regex.Pattern.matches("[RQrq1-6]*", args[0])){
      System.out.println("OK: "+args[0]);
    } else {
      System.out.println("Not OK: " +args[0]);
    }
  }
}

Пример:

burner@firefighter:~$ java Test rr
OK: rr
burner@firefighter:~$ java Test rrRR
OK: rrRR
burner@firefighter:~$ java Test rrRRa
Not OK: rrRRa

Теперь вы, вероятно, пытаетесь сопоставить все символы в командной строке. Интерпретатор команд разделяет их на отдельные строки перед запуском приложения. Вы можете сделать так, как предлагает Майлз, но затем вы обработаете некоторые команды, прежде чем обнаружите неправильный ввод. Вы можете сделать это вместо:

String myargs = "";
for (String arg : args) {
  myargs += arg;
}
if(java.util.regex.Pattern.matches("[RQrq1-6]*", myargs)){
...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...