在java中匹配SubString

时间:2014-06-18 07:18:40

标签: java string arraylist substring string-matching

我有一个存储在arraylist中的输入数据。 在遍历列表时,输出是

Input ----------- [0 Overcast 1 High 2 Normal 3 Weak ]
Input ----------- [0 Rainy 1 Mild 2 High 3 Strong ]
Input ----------- [0 Rainy 1 Mild 2 Normal 3 Weak ]

并在另一个arraylist中统治

  

规则----------- [0阴转是,0多雨3强不,0多雨3   弱是,0 Sunny 2 High No,0 Sunny 2 Normal Yes]

我期待输出为

[0 Overcast 1 High 2 Normal 3 Weak Yes]
[0 Rainy 1 Mild 2 High 3 Strong No]
[0 Rainy 1 Mild 2 Normal 3 Weak Yes]

通过查看规则集,我必须为输入添加标签。 为此我尝试在输入和规则集之间进行匹配

for(String ruleSet : addRule){ //ruleset
 for(String lineSet : getLine){ //inputline
   if (lineSet.matches("(.*)"+ruleSet+"(.*)")) {
     System.out.println("got----------------"+lineSet+"***"+ruleSet);
     break;
   }
   else{
     System.out.println("Not found----------------"+lineSet+"***"+ruleSet);
   }
 }
}

但我的结果是like this

0 Overcast 1 High 2 Normal 3 Weak Yes0 Overcast Yes不匹配。虽然它是一个子集。

我做错了什么。

1 个答案:

答案 0 :(得分:2)

如果我理解正确,您有两个String列表:

  1. getLine是表示输入行
  2. 的字符串列表
  3. addRule是表示规则集的字符串列表。
  4. 每个规则包含几个需要与输入行匹配的部分,以及在匹配时应该使用的结果。

    (您似乎将此结果称为“类路径”,尽管该术语在Java的上下文中具有非常特定的含义。)

    所以这一行:

    0 Overcast 1 High 2 Normal 3 Weak
    

    符合规则

    0 Overcast
    

    因为它包含子串“0 Overcast”,但也违反规则:

    0 Overcast 3 Weak
    

    因为该行包含子串“0 Overcast”和“3 Weak”,即使整个规则没有显示为该行中的子字符串。

    我猜你所寻找的是一个子集搜索,也许看到this answer并尝试使用它,但是在字符串之间进行子集匹配很复杂,并且使用正则表达式是可能的,但是有点比你尝试的更棘手,所以我建议尝试使用更简单的解决方案。

    具体来说,只做.matches("(.*)"+ruleSet+"(.*)")就不会做你想做的事。

    如果我对您的问题的解释是正确的,请在评论中告诉我,我会尽力帮您找到解决方案。

    所以,假设您已经控制了规则集,我可能会创建一个看起来像这样的Rule类:

    public class Rule {
        public List<String> parts;
        public String result;
    
        public Rule(String result, String... parts) {
            this.parts = new ArrayList<>();
            for(String part : parts) {
                this.parts.add(part);
            }
            this.result = result;
        }
    
        public String match(String line) {
            for(String part : parts) {
                if (!line.contains(part)) return null;
            }
            return result;
        }
    }
    

    注意match如何实现:如果任何部分不匹配,则匹配失败。

    (我使用varargs作为构造函数,但如果你愿意,你可以传递一个列表。)

    然后你可以像这样初始化规则集:

    List<Rule> ruleSet = new ArrayList<>();
    ruleSet.add(new Rule("Yes", "0 Overcast"));
    ruleSet.add(new Rule("No", "0 Rainy", "3 Strong"));
    ruleSet.add(new Rule("Yes", "0 Rainy", "3 Weak"));
    ...
    

    当你按照规则进行循环时,如果没有匹配则调用match获取null,如果匹配则调用结果。

    for(Rule rule : ruleSet) {
        for(String line : getLine) {
           String result = rule.match(line);
           if (result != null) {
              ...
    

    或者,您可以将规则编写为正则表达式,如下所示:

    String rule = ".*0 Rainy.*3 Strong.*";
    if(line.matches(rule)) {
        ...
    

    但是在你有时间了解它们之前,你应该避免使用正则表达式。它们是强大的工具,但有许多警告。


    如果需要将规则集保存在文本文件中,那么您将不得不编写一个方法将行转换为Rule对象,可能作为不同的构造函数。这是一种方法:

    public class Rule {
        ...
        public Rule(String line) {
            this.parts = new ArrayList<>();
            String number = null;
            for (String s : line.split()) {
                if (s.equals("Yes") || s.equals("No")) {
                    this.result = s;
                    return;
                }
                if (number == null) {
                    number = s;
                } else {
                    this.parts.add(number + " " + s);
                    number = null;
                }
            }
        }