如何在java中限制Matcher或Pattern?

时间:2018-03-21 19:50:36

标签: java

如何在java中限制匹配器只匹配所需的字符串?以下是我尝试的代码,但是预期的匹配应该像" Invoice Received"但它只打印" Invoice"在控制台上。

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class JavaTest {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        List<String> actionList = new ArrayList<String>();
        actionList.add("Invoice");
        actionList.add("Invoice Received");

        List<String> notes = new ArrayList<String>();
        notes.add("Invoice Received123");

        for (String note : notes) {
            for (String action : actionList) {

                Pattern pattern = Pattern.compile(action);
                Matcher matcher = pattern.matcher(note);

                if(matcher.find()) {
                    System.out.println("Update History As : "+action);

                }
            }
        }

    }

}

2 个答案:

答案 0 :(得分:1)

            if(matcher.find()) {
                System.out.println("Update History As : "+action);
                break;
            }

这破坏了你的代码。从字面上看。当模式匹配时,break语句退出内部for循环。因此,Invoice Recieved永远不会有机会匹配。

最初这是解释的问题,但问题已经成为关于这个特定问题的流量控制。作为建议的解决方案,这里是Note对象没有多态的示例,而是控制代码。

public class Note {
    public static final int INVOICE = 1;
    public static final int INVOICE_RECEIVED = 2;

    public int noteType;
    public String userText;

    public Note(int noteType, String userText) {
        this.noteType = noteType;
        this.userText = userText;
    }

    public void doSomething() {
        switch(noteType) {
            case INVOICE:
                // do something with the INVOICE type
                break;
            case INVOICE_RECEIVED:
                // do something with the INVOICE_RECEIVED type
                break;
         }
    }

}

然后,您可以按Note创建一个收到发票的Note newNote = new Note(Note.INVOICE_RECEIVED, "this is some user text");对象,并将它们添加到列表中,类似于您正在执行的操作,并相应地处理它们。根据您的音符数量,多态设计可能会更好,或者至少更清晰。但这是使用控制代码的方式。

答案 1 :(得分:0)

您需要订购您正在寻找的模式,以便一种模式的前缀始终位于该模式之后。具体而言:

List<String> actionList = new ArrayList<String>();
actionList.add("Invoice Received"); /* Make this take precedence... */
actionList.add("Invoice");          /* ... over this. */

然后将break放回到您的比赛案例中,或者每个“已开票的已收到”说明也将作为“发票”说明处理:

if(matcher.find()) {
  System.out.println("Update History As : "+action);
  break;
}

一般来说,这种系统很容易受到漏洞的影响。如果您对此流程的输入有任何控制权,请对其进行修改,以使备注类型明确,而不是从其内容中猜到。