Java正则表达式:按特定顺序检查

Java正则表达式:按特定顺序检查,java,regex,Java,Regex,我有以下正则表达式数组: String[] array = new String[] { "(car)|(truck)|(bus)|(van)", //4) transportation "(w)|(x)|(y)|(z)", //1) options "1|2|3|4", //2) numbers "(red)|(blue)|(green)|(pink)|(yellow)" //3) color }; 我有以下字符串: String s= "1 blue w truc

我有以下正则表达式数组:

String[] array = new String[] { 
  "(car)|(truck)|(bus)|(van)", //4) transportation
  "(w)|(x)|(y)|(z)", //1) options
    "1|2|3|4", //2) numbers
    "(red)|(blue)|(green)|(pink)|(yellow)" //3) color
};
我有以下字符串:

String s= "1 blue w truck";
我试图迭代这个字符串,看看字符串中的任何单词是否与数组中的任何正则表达式匹配。这就是我正在做的:

for(int i=0; i<array.length;i++){
      Pattern word = Pattern.compile(array[i]);
      Matcher match = word.matcher(s);
      while(match.find() ){
        System.out.println(String.format(" Using regex %d:  %s",i,match.group()));
      }
    }
但我希望以下是输出:

Using regex 2:  1
Using regex 3:  blue
Using regex 1:  w
Using regex 0:  truck

我希望字符串中的单词保持相同的顺序,而不改变数组中正则表达式的顺序。

这里有一个使用pojo的解决方案,它将包含匹配的相关信息(这里任意称为
MatchInfo
),以及一个
TreeSet
根据所需标准(给定
字符串中的匹配索引)对匹配进行排序


您将需要在字符串的部分上循环。这可能会降低效率,因为您还需要循环遍历每个正则表达式,直到找到匹配项为止

类似于以下内容的内容应该会有所帮助:

String[] parts = s.split(" ");
for (int i = 0; i < parts.length; i++) {
    for (int r; r < array.length; r++) {
        Pattern word = Pattern.compile(array[i]);
        Matcher match = word.matcher(s);
        if (match.find()) {
            // print out stuff
            break;
        }
    }
}
String[]parts=s.split(“”);
对于(int i=0;i
无需在每次迭代时编译模式

        Pattern[] array = new Pattern[] { 
              Pattern.compile("^((car)|(truck)|(bus)|(van))"), //4) transportation
              Pattern.compile("^((w)|(x)|(y)|(z))"), //1) options
              Pattern.compile("^(1|2|3|4)"), //2) numbers
              Pattern.compile("^((red)|(blue)|(green)|(pink)|(yellow))") //3) color
            };
    String s= "1 blue w truck";

    while(s.length() > 0) {
        for(int i=0; i<array.length;i++){
          Matcher match = array[i].matcher(s);
          if(match.find()) {
              String substr = match.group();
              System.out.println(String.format(" Using regex %d:  %s",i, substr));
              s = s.substring(substr.length()).trim();
          }
        }
    }
模式[]数组=新模式[]{
模式。编译(“^((汽车)|(卡车)|(公共汽车)|(货车))”,//4)运输
Pattern.compile(“^((w)|(x)|(y)|(z))”,//1)选项
Pattern.compile(“^(1 | 2 | 3 | 4)”),//2)个数字
模式。编译(^((红色)|(蓝色)|(绿色)|(粉色)|(黄色)))//3)颜色
};
字符串s=“1蓝色卡车”;
而(s.length()>0){

对于(int i=0;i另一种可能是使用更复杂的正则表达式,并使用捕获组。我添加了一点额外内容,通过在正则表达式中使用命名捕获组为您提供一个类型字符串。如果您不喜欢,可以使用groupCount()和group(i)迭代以返回匹配的组索引

    public static void main() {
      Pattern pattern = Pattern.compile("(?<transportation>(?:car)|(?:truck)|(?:bus)|(?:van))|(?<options>[wxyz])|(?<numbers>[1-4])|(?<color>(?:red)|(?:blue)|(?:green)|(?:pink)|(?:yellow))");

      String s = "1 blue w truck";

      Matcher match = pattern.matcher(s);
      while(match.find()) {
        printGroupMatch(match, "transportation");
        printGroupMatch(match, "options");
        printGroupMatch(match, "numbers");
        printGroupMatch(match, "color");
      }
    }

    private static void printGroupMatch(Matcher match, String gName) {
      String groupValue = match.group(gName);
      if(groupValue != null){
        System.out.println(String.format(" Using regex %s:  %s", gName, groupValue));
    }
  }

那么,您需要在字符串的部分上循环。这可能会有点效率低下,因为您还需要循环每个正则表达式,直到找到匹配项。将模式数组组合到一个正则表达式对您来说是有效的解决方案吗?还是模式数组是必须的?@Alexander我不能这样做。我有为了区分我在stringAs@dimplex中找到的东西在他们的答案中指出了什么,我在每次迭代中都不必要地重新编译数组中的模式。优化将涉及预编译所有模式,正如他们的答案所示。
String[] parts = s.split(" ");
for (int i = 0; i < parts.length; i++) {
    for (int r; r < array.length; r++) {
        Pattern word = Pattern.compile(array[i]);
        Matcher match = word.matcher(s);
        if (match.find()) {
            // print out stuff
            break;
        }
    }
}
        Pattern[] array = new Pattern[] { 
              Pattern.compile("^((car)|(truck)|(bus)|(van))"), //4) transportation
              Pattern.compile("^((w)|(x)|(y)|(z))"), //1) options
              Pattern.compile("^(1|2|3|4)"), //2) numbers
              Pattern.compile("^((red)|(blue)|(green)|(pink)|(yellow))") //3) color
            };
    String s= "1 blue w truck";

    while(s.length() > 0) {
        for(int i=0; i<array.length;i++){
          Matcher match = array[i].matcher(s);
          if(match.find()) {
              String substr = match.group();
              System.out.println(String.format(" Using regex %d:  %s",i, substr));
              s = s.substring(substr.length()).trim();
          }
        }
    }
    public static void main() {
      Pattern pattern = Pattern.compile("(?<transportation>(?:car)|(?:truck)|(?:bus)|(?:van))|(?<options>[wxyz])|(?<numbers>[1-4])|(?<color>(?:red)|(?:blue)|(?:green)|(?:pink)|(?:yellow))");

      String s = "1 blue w truck";

      Matcher match = pattern.matcher(s);
      while(match.find()) {
        printGroupMatch(match, "transportation");
        printGroupMatch(match, "options");
        printGroupMatch(match, "numbers");
        printGroupMatch(match, "color");
      }
    }

    private static void printGroupMatch(Matcher match, String gName) {
      String groupValue = match.group(gName);
      if(groupValue != null){
        System.out.println(String.format(" Using regex %s:  %s", gName, groupValue));
    }
  }
 Using regex numbers:  1
 Using regex color:  blue
 Using regex options:  w
 Using regex transportation:  truck