【问题标题】:Matching a SubString in java在java中匹配子字符串
【发布时间】:2014-08-08 09:08:09
【问题描述】:

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

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 ]

并在另一个数组列表中进行规则

规则 -----------[ 0 阴是,0 雨 3 强不,0 雨 3 弱 是,0 晴 2 高 否,0 晴 2 正常 是]

我期望输出为

[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 不匹配。尽管它是一个子集。

我是不是做错了什么。

【问题讨论】:

  • 反对者请发表评论
  • 您将不得不以更好的方式解释您想要实现的目标。目前还不清楚。
  • 您可以控制规则集吗?您可以用不同的方式编写它们,还是将它们作为输入?
  • 我可以控制规则集

标签: java string arraylist substring string-matching


【解决方案1】:

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

  1. getLine 是表示输入行的字符串列表
  2. addRule 是表示规则集的字符串列表。

每个规则包含几个需要与输入行匹配的部分,以及在匹配时应使用的结果。

(您似乎将此结果称为“类路径”,尽管该术语在 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+"(.*)") 不会做你想做的事。

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

继续

所以,假设您可以控制规则集,我可能会创建一个如下所示的 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;
            }
        }
    }

【讨论】:

  • 但是 lineSet.matches("(.*)"+ruleSet+"(.*)") 也会匹配子字符串对吗?我尝试了你所说的方法,它也行不通,因为它在 [0 Overcast 1 High 2 Normal 3 Weak] *** [0 Overcast] 我正在尝试匹配子字符串
  • 或者有没有其他方法来存储规则集并通过它进行迭代?
  • @SreeVeni 如果您有一个规则集,那么无论如何您可能都必须遍历它。我不明白你的第一条评论。
  • 我想说的是..我尝试从规则集中删除类路径并匹配,但它们仍然与输入行不匹配
  • 是的,这就是我的意思:)。它是决策树预测的一部分。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-08-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-20
  • 2017-08-03
  • 2011-11-08
相关资源
最近更新 更多