使用java中的regex进行模式匹配和范围检查

时间:2009-11-14 20:36:17

标签: java regex

我的应用程序基本上会通过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]){

}

我很难掌握匹配正则表达式的匹配方法(以上不起作用),我想避免使用多个if-else条件来单独检查每个有效输入。

这可以通过模式匹配器同时进行范围检查来实现吗?

感谢任何提示!

5 个答案:

答案 0 :(得分:3)

你的正则表达式不太正确。

撰写时:[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

它使用一种称为“捕获组”的概念。捕获组是正则表达式的一部分,其被分配一个数字,以便可以提取匹配的特定符号串。我们在这里使用捕获组从可选空格中拉出符号。

答案 1 :(得分:2)

我会被诱惑而不是用regexp来做这件事,因为它只匹配并提取特定的模式,并没有真正帮助决定对特定字符串做什么(使用一个正则表达式)。

相反,我会查看命令行选项库,例如Apache Commons CLI。它更适合您的需求。

答案 2 :(得分:1)

我认为你需要匹配传入的每个参数。所以:

for(int i = 0; i < args.length; i++) {
   if (Pattern.matches("[RQrq1-6]+", args[i]){
     <do stuff>
   }
}

答案 3 :(得分:0)

以下课程对我来说很好(正如我所期待的那样):

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

现在,您可能正在尝试匹配命令行中的所有字符。命令解释器在启动应用程序之前将它们分离为单独的字符串。你可以按照Myles的建议去做,但是在检测到错误输入之前你会处理一些命令。你可以这样做:

String myargs = "";
for (String arg : args) {
  myargs += arg;
}
if(java.util.regex.Pattern.matches("[RQrq1-6]*", myargs)){
...

答案 4 :(得分:0)

如果我正确地阅读了你的问题,你想要像这样打电话给你的程序:

$ myprog 153r34r2q

然后,你的程序会通过一串单字母命令并执行它们(也许是你在其他参数中传入的东西)。

为此,您的正则表达式解决方案几乎没问题(使用/[RrQq1-6]+/代替/[RrQq1-6]*/)。

但是,我怀疑你确实想要运行你的程序,然后在程序运行时接受用户命令(这个假设是由你的命令“重放”和“退出”的名称引起的,这些命令并不多否则意义)。为此,args[]根本不适合。相反,您将不得不使用一个接受单击键作为输入的主循环。在这种情况下,我不会使用正则表达式来测试单个字符,而是使用switch子句来调度具有默认情况的不同命令以捕获无效输入。

编辑:在阅读完您的评论后,我建议您可以在Command Pattern上使用某些内容。