Java Regex:检查特定顺序

时间:2016-05-04 13:20:07

标签: 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 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 0:  truck
Using regex 1:  w
Using regex 2:  1
Using regex 3:  blue

但我希望以下内容成为输出:

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

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

4 个答案:

答案 0 :(得分:3)

这是一个使用pojo的解决方案,其中包含匹配的相关信息(此处任意称为MatchInfo),以及TreeSet按所需标准排序匹配(匹配的索引)给定的String)。

// your patterns
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
};
// your input
String s = "1 blue w truck";

// the definition of the relevant information you want to keep on matches
class MatchInfo implements Comparable<MatchInfo>{
    int index;
    Integer start;
    String match;
    MatchInfo(int index, int start, String match) {
        this.index = index;
        this.start = start;
        this.match = match;
    }
    @Override
    // comparing start index of the match within original string
    public int compareTo(MatchInfo o) {
        return start.compareTo(o.start);
    };
}
// orders unique elements by natural ordering, as defined by Comparable 
// implementation
Set<MatchInfo> groups = new TreeSet<>();

// your original iteration
for (int i = 0; i < array.length; i++) {
    Pattern word = Pattern.compile(array[i]);
    Matcher match = word.matcher(s);
    while (match.find()) {
        // adding new "MatchInfo" to the set
        groups.add(new MatchInfo(i, match.start(), match.group()));
    }
}

// iterating and printing the info
for (MatchInfo m: groups) {
    System.out.printf("Using regex %d: %s%n", m.index, m.match);
}

<强>输出

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

答案 1 :(得分:2)

您需要循环部分字符串。这可能效率稍低,因为您还需要循环遍历每个正则表达式,直到您也匹配到匹配项。

以下内容应该有所帮助:

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;
        }
    }
}

答案 2 :(得分:0)

不必在每次迭代时编译模式。

        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();
          }
        }
    }

答案 3 :(得分:0)

另一种可能性是使用更复杂的正则表达式并使用捕获组。我添加了一些额外的东西,通过在正则表达式中使用命名捕获组为您提供类型字符串。如果您不喜欢它,可以使用 groupCount() group(i)迭代来返回匹配的组索引。

$("#span id").trigger("click");

这将返回这样的内容:

    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));
    }
  }